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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:05:54  来源:igfitidea点击:

How do I stop name-mangling of my DLL's exported function?

c++cexternname-mangling

提问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 __stdcallconvention. The @Nindicates 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