C++ 如何停止对 DLL 导出函数的名称修改?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1467144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I stop name-mangling of my DLL's exported function?
提问by Slapout
I'm trying to create a DLL that exports a function called "GetName". I'd like other code to be able to call this function without having to know the mangled function name.
我正在尝试创建一个导出名为“GetName”的函数的 DLL。我希望其他代码能够调用此函数而无需知道损坏的函数名称。
My header file looks like this:
我的头文件如下所示:
#ifdef __cplusplus
#define EXPORT extern "C" __declspec (dllexport)
#else
#define EXPORT __declspec (dllexport)
#endif
EXPORT TCHAR * CALLBACK GetName();
My code looks like this:
我的代码如下所示:
#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");
}
When I build, the DLL still exports the function with the name: "_GetName@0".
当我构建时,DLL 仍然导出名为“_GetName@0”的函数。
What am I doing wrong?
我究竟做错了什么?
采纳答案by Dewfy
Small correction - for success resolving name by clinet
小更正 - 成功解析 clinet 名称
extern "C"
must be as on export side as on import.
必须在出口方面和进口方面一样。
extern "C" will reduce name of proc to: "_GetName".
extern "C" 将 proc 的名称减少为:"_GetName"。
More over you can force any name with help of section EXPORTS in .def file
此外,您可以借助 .def 文件中的 EXPORTS 部分强制使用任何名称
回答by Mark Rushakoff
This is normal for a DLL export with a __stdcall
convention. The @N
indicates the number of bytes that the function takes in its arguments-- in your case, zero.
这对于具有__stdcall
约定的 DLL 导出来说是正常的。该@N
指示的字节,并且函数只在其参数的数目-在你的情况下,零。
Note that the MSDN page on Exporting from a DLLspecifically says to "use the __stdcall calling convention" when using "the keyword __declspec(dllexport) in the function's definition".
请注意,有关从 DLL 导出的 MSDN 页面特别指出在使用“函数定义中的关键字 __declspec(dllexport)”时“使用 __stdcall 调用约定”。
回答by sn0w
the right answer is the following:
正确答案如下:
extern "C" int MyFunc(int param);
and
和
int MyFunc(int param);
is two declarations which uses different internal naming, first - is in C-style, second - in the C++ style.
是两个使用不同内部命名的声明,第一个是 C 风格,第二个是 C++ 风格。
internal naming required for build tools to determine which arguments function receives, what type returns etc, since C++ is more complicated (oop's, overloaded, virtual functions etc) - it uses more complicated naming. calling convention also affects both c and c++ namings.
构建工具需要内部命名来确定函数接收哪些参数、返回什么类型等,因为 C++ 更复杂(oop、重载、虚函数等)——它使用更复杂的命名。调用约定也会影响 c 和 c++ 命名。
both this styles of naming is applied when using __declspec(dllexport) in the same manner.
当以相同的方式使用 __declspec(dllexport) 时,会应用这两种命名风格。
if you want to omit name mangling of exported routine, add a module definition file to your project, type in it (in this case you not required to declspec dllexport):
如果您想省略导出例程的名称修改,请将模块定义文件添加到您的项目中,输入它(在这种情况下,您不需要 declspec dllexport):
LIBRARY mylib
EXPORTS
MyFunc
this will omit explicit name decoration (samples below).
这将省略显式名称修饰(下面的示例)。
_MyFunc (c style, __cdecl)
_MyFunc@4 (c style, __stdcall)
?MyFunc@@YAHH@Z (c++ style, __cdecl)
?MyFunc@@YGHH@Z (c++ style, __stdcall)
回答by vga None
You can use the "-Wl,--kill-at" linker switch to disable name mangling.
您可以使用“-Wl,--kill-at”链接器开关来禁用名称修改。
For example, in Code::Blocks, in the custom linker settings, add: -Wl,--kill-at
例如,在 Code::Blocks 中,在自定义链接器设置中,添加:-Wl,--kill-at