使用Extern C和DLLEXPORT与模块定义(MSVC ++)的STDCALL名称熔融(MSVC ++)
-
13-10-2019 - |
题
我试图导出一个简单的测试功能,以使DLL与应用程序(FYI:MIRC)一起使用,该应用程序指定了调用约定为:
int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
现在,要从应用程序打电话,我会使用 test_func 但是我已经注意到,由于名字杂交,它并不像我想象的那么简单。
通过类似的主题,我了解到使用 外部“ C” 结合 __declSpec(dllexport) 是一种将熔断器删除到模块定义(.def)的等效(有点)方法。但是,当使用extern/dllexport方法时,我的功能(例如)始终是 _TEST_FUNC@数字 而.DEF删除了与我需要导出的应用程序一起使用的所有熔断。
有人可以解释为什么这是吗?我只是对这两种方法感到好奇。谢谢!
解决方案
DLLEXPORT/导入旨在将其重新加载,而不是使用GetProcaddress的旧C库。您看到的杂乱无章的是所有Microsoft编译器在很长一段时间内为__STDCALL函数所做的工作。您的目标很可能会期望__cdecl功能,而不是__ stdcall,但如果没有,则需要使用.def文件来专门解开名称。
其他提示
extern "C"
与STDCALL无关:它仅声明C ++名称Mangling(又称类型安全链接;将类型信息包含在符号名称中)是禁用的。您需要独立于使用C呼叫约定还是使用STDCALL调用约定的情况。
在stdcall呼叫约定中,Callee从堆栈中删除了参数。为了使该安全性,导出的名称包含Callee将从堆栈中删除的字节数。
如果您要导出的申请,则不需要 @number
__stdcall
. 。当您将其声明为 declspec(dllexport)
, ,您应该在DLL中获得一个未装饰的名称。
在DEF文件中,您可以随意调用该功能;未进行其他检查。