我正在尝试创建一个导出名为“GetName”的函数的DLL。我希望其他代码能够调用此函数,而无需知道损坏的函数名称。
我的头文件如下所示:
#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif
EXPORT TCHAR * CALLBACK GetName();
我的代码如下所示:
#include <windows.h>
#include "PluginOne.h"
int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
{
return TRUE ;
}
EXPORT TCHAR * CALLBACK GetName()
{
return TEXT("Test Name");
}
当我构建时,DLL仍然导出名为“_GetName @ 0”的函数。
我做错了什么?
答案 0 :(得分:23)
小修正 - 通过clinet成功解析名称
extern "C"
必须与导出方面相同。
extern“C”会将proc的名称减少为:“_ GetName”。
您可以在.def文件
的EXPORTS部分的帮助下强制使用任何名称答案 1 :(得分:9)
对于具有__stdcall
约定的DLL导出,这是正常的。 @N
indicates the number of bytes that the function takes in its arguments - 在您的情况下为零。
注意the MSDN page on Exporting from a DLL在函数定义中使用“关键字__declspec(dllexport)”时特别说“使用__stdcall调用约定”。
答案 2 :(得分:6)
正确答案如下:
extern "C" int MyFunc(int param);
和
int MyFunc(int param);
是两个使用不同内部命名的声明,第一个是C风格,第二个是C ++风格。
构建工具需要内部命名来确定函数接收哪些参数,返回什么类型等等,因为C ++更复杂(oop,重载,虚函数等) - 它使用更复杂的命名。调用约定也会影响c和c ++命名。
当以相同的方式使用__declspec(dllexport)时,将应用这种命名方式。
如果要省略导出例程的名称修改,请将模块定义文件添加到项目中,键入(在这种情况下,您不需要declspec dllexport):
LIBRARY mylib
EXPORTS
MyFunc
这将省略明确的名称装饰(下面的示例)。
_MyFunc (c style, __cdecl)
_MyFunc@4 (c style, __stdcall)
?MyFunc@@YAHH@Z (c++ style, __cdecl)
?MyFunc@@YGHH@Z (c++ style, __stdcall)
答案 3 :(得分:2)
您可以使用“-Wl, - kill-at”链接器开关来禁用名称修改。
例如,在Code :: Blocks中,在自定义链接器设置中,添加: -Wl, - 杀-在