我在Visual Studio 2013中使用模块定义文件(.def)来选择性地导出符号以生成导入库。我似乎无法导出完全内联在头中的函数。我不希望使用declspec(dllexport)
,因为它使反转我的应用程序变得更容易,因为每个dllexported函数都将有其原始签名。比较:dllexport(左)与.def文件(右):![1] ´。在这种情况下,整个"Obj_AI_Base"类都是dllexported。简而言之:我不希望反向器知道位于(例如)0x123456的函数名为obj_AI_Base::GetHealth(),但仍然可以让第三方API访问它。
GameObject.h:
class GameObject
{
inline float Health()
{
return 1000;
}
};
我现在希望导出Health()
方法。
此方法的符号如下(从dumbin/exports导出):
?Health@GameObject@Native@MyTool@@QAEMXZ
把它插入我的.def文件:
LIBRARY MyTool
EXPORTS
?Health@GameObject@Native@MyTool@@QAEMXZ @1 NONAME
将导致未解析的外部符号错误,尽管方法内联在头文件中。解决方法是将方法体移动到.cpp文件中。
GameObject.h:
class GameObject
{
float Health();
};
GameObject.cpp:
class GameObject
{
GameObject::Health()
{
return 1000;
}
};
这将导致.def文件按预期工作。由于这个项目有很多这样的属性,其方法体通常只有1行长,这对我来说不是一个解决方案。为什么编译器在头中定义方法体时找不到符号,而使用__declspec(dllexport)
时效果很好?
使用.def文件而不是__declspec(dllexport)
并不意味着导出内联函数的规则不适用于您。
无法显式导出inline
函数的原因是它是内联的,而不是导出它的方式。该函数在.dll中没有一个可以导出的定义。因此,.def文件和显式dllexport
属性都无法导出它。