我需要有关LNK2019解决方法的建议
I need advice about a LNK2019 workaround
正如先前在此处讨论的那样,我正在尝试找到LNK2019问题的解决方法,该问题在构建利用C 模板的静态库时会出现,并将源与标头分开以保持来自其他项目的私人代码。我相信我几乎得出了结论(对于我的特定情况),但是我不确定这是否是正确/最好的方法,并且想知道是否有人有任何建议,改进/评论添加?
目标是进行某种类型检查,以查看模板的签名是否与目标原型函数的签名相匹配,进行一些私人处理,并返回是否成功。请注意,我已从上述链接中的解决方案的先前版本中删除了SdkHookMgr.h
和SdkHookMgr.cpp
,并将所有内容汇回了 SdkLib.h
和 SdkLib.cpp
,进入静态课程以稍微清晰。
sdklib.h:
#include <typeinfo>
#ifdef MY_EXPORTS
# define MYDECL __declspec(dllexport)
#else
# define MYDECL
#endif
// Prototypes
typedef HMODULE (WINAPI *HookLoadLibraryA)( LPCSTR lpFileName );
//...
class CHook;
class CHookManager;
MYDECL BOOL WINAPI ValidateHook( CHook *hook );
class CHook
{
public:
CHook() : m_type(NULL), m_target(NULL), m_result(FALSE) {};
CHook( const char *type, PVOID target ) : m_type(type), m_target(target) {
m_result = ValidateHook(this);
};
const char *m_type;
PVOID m_target;
BOOL m_result;
};
class CHookManager
{
public:
template <typename HookFunction> static BOOL Hook(HookFunction target)
{
const type_info& type = typeid(HookFunction);
CHook *hook = new CHook( type.name(), target );
return hook->m_result;
}
};
sdklib.cpp:
#include <SdkLib.h>
IDXDECL BOOL WINAPI ValidateHook( CHook *hook )
{
// Do type checking, private processing, etc here...
return TRUE;
}
demodll.cpp:
#include <SdkLib.h>
HMODULE WINAPI Hooked_LoadLibraryA( LPCSTR lpFileName )
{
DebugBreak();
}
// The function that starts the rollercoaster.
// - Syntax: Hook< prototype >( target )
if!(CHookManager::Hook<HookLoadLibraryA>(Hooked_LoadLibraryA))
cout << "Failed to create hook for LoadLibraryA!" << endl;
您可能会发现typeid
的结果在DLL和主程序之间不一致。(例如,请参阅不同DLL的TypeID结果。)
由于您可能的挂钩列表有限,因此使我的超载功能比模板更好。然后,您将没有DLL问题,并且在编译时将检查每个挂钩的有效性。这是我想的那种事情的例子;显然,实际上,您将其分为单独的定义和声明,而定义则存在于DLL中,因此所有这些都已干净地分开。
class CHookManager {
public:
BOOL Hook(HookLoadLibraryA hook) {
assert(sizeof hook<=sizeof(uintptr_t));
return ValidateHook((uintptr_t)hook,"LoadLibraryA");
}
BOOL Hook(HookLoadLibraryW hook) {
assert(sizeof hook<=sizeof(uintptr_t));
return ValidateHook((uintptr_t)hook,"LoadLibraryW");
}
};
(请注意,这显示出这种方法的一个缺点 - 您只能每个功能签名。>
(如果有的话,您可能想用编译时间断言代替。)
ValidateHook将使用strcmp
来找出挂钩的钩子。一旦确定了它是哪个挂钩,它将将uintptr_t
施加到适当的功能指针类型。它知道该指针最初是该挂钩的正确类型的,因为您使用的是C 过载机制来完成所有操作。(或者,对于所有钩类型,您可以说出一个枚举,而不是通过字符串传递 - 取决于您。关键部分是您对所传递的值有完全控制,因此DLL和调用代码肯定使用匹配值。)
此代码生成有点累人,但是如果您已经有Typedef名称的列表,则可以在选择的编辑器中使用正则表达式搜索和替换或键盘宏创建相应的代码。或者,您可以使用所谓的" X-MaCro"之类的东西来自动化整个事物的产生。
- 有没有办法在 c++ 中同时生成随机数?如果没有,是否有解决方法?
- 使用 Git 处理 C++ Visual Studio 2019 解决方案的外部依赖项源代码管理的最佳方法是什么?
- 在 c++ 中解决段树以外的范围查询的有效方法是什么?
- 此解决方案中生成更改的方法数量(自上而下)有什么问题?
- 从 int 中剥离位时,编译器会警告一个转换,但不警告其他转换.有解决方法吗?
- 是否有解决方法可以在 c++ 中为 short 定义用户定义的文字?
- 不为 emplace() 定义构造函数的解决方法
- 当只有静态方法受到影响时,如何解决C++中的链接器错误?
- 删除复制构造函数的 Intel 13.1.2 中不良C++行为的解决方法
- 函数模板部分专业化-有什么解决方法吗
- 带boost的过载模糊性:可选,解决方法
- 继承构造函数和其他变量的解决方法
- 解决虚拟方法的歧义继承的两种方法
- 解决歧义的方法
- C++ 解决方法:"从类型"B*"的表达式初始化类型"C*&"的引用无效"
- 对前向声明类型进行unique_ptr的解决方法
- 必须使用尾随返回类型的示例,因为无法用旧方法解决问题
- 如何通过动态规划方法解决这个问题?
- extern可以解决这个问题吗,或者我可以通过其他方法解决这个问题吗?
- 从析构函数调用虚拟方法-解决方法