C++ 使用extern c和dllexport与模块定义(msvc+;+;)对stdcall名称进行破坏

C++ 使用extern c和dllexport与模块定义(msvc+;+;)对stdcall名称进行破坏,c++,visual-c++,dllexport,name-mangling,stdcall,C++,Visual C++,Dllexport,Name Mangling,Stdcall,我试图导出一个简单的dll测试函数,以便与指定调用约定为: int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause) 现在,要从应用程序中调用它,我将使用test_func,但我注意到,由于名称混乱,它并不像我想象的那么简单 通过这里的类似主题,我了解到使用extern“C”与\u declspec(dllexport)相结合是消除模块定义(.def)混乱的一种

我试图导出一个简单的dll测试函数,以便与指定调用约定为:

int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
现在,要从应用程序中调用它,我将使用test_func,但我注意到,由于名称混乱,它并不像我想象的那么简单

通过这里的类似主题,我了解到使用extern“C”\u declspec(dllexport)相结合是消除模块定义(.def)混乱的一种等效(稍微)方法。但是,当使用extern/dllexport方法时,我的函数(作为示例)总是\u test_func@numbers而.def删除了与我需要导出到的应用程序一起使用所需的所有损坏

有人能解释一下为什么会这样吗?我只是好奇这两种方法。谢谢

<代码>外部“C”<代码>与STDCULL无关:它只声明C++名称的MARGLY(AKA类型安全链接;包含符号名中的类型信息)禁用。您需要独立于使用C调用约定还是stdcall调用约定来使用它

在stdcall调用约定中,被调用方从堆栈中删除参数。为了确保安全,导出的名称包含被调用方将从堆栈中删除的字节数

如果要导出到的应用程序要求在名称中不添加
@number
后缀,则可能意味着它需要C调用约定。因此,您应该停止将函数声明为
\uu stdcall
。当您将其声明为
declspec(dllexport)
时,应该在DLL中获得一个未修饰的名称


在DEF文件中,您可以随意调用函数;不执行任何其他检查。

dllexport/import被设计为自己加载,而不是使用GetProcAddress的旧C库。您所看到的混乱是所有Microsoft编译器长期以来对stdcall函数所做的。最有可能的情况是,您的目标需要一个u cdecl函数,而不是u stdcall,但如果不是,则需要使用一个.def文件来专门清除名称。

windows api函数是stdcall,但没有@number,在windows上,这样做是标准做法。