如何避免名称混淆?
Posted
技术标签:
【中文标题】如何避免名称混淆?【英文标题】:How can i avoid name mangling? 【发布时间】:2009-02-07 21:40:38 【问题描述】:如何避免 C++ 中的名称混淆?
【问题讨论】:
【参考方案1】:你不能。它内置在编译器中,允许您重载函数并在不同的类中拥有具有相同名称的函数等。但是你可以编写像 C 函数一样被破坏的函数。这些可以从 C 代码中调用。但是那些不能被重载,也不能被“普通”的 C++ 函数指针调用:
extern "C" void foo()
上面的函数将像编译器的 C 函数一样被修改。这可能包括对名称没有任何更改,或者一些更改,例如在它前面的前导“_”左右。
【讨论】:
只是一个小问题:这样的函数当然可以从 C++ 函数指针中调用: extern "C" void foo() printf("foo\n"); int main() 无效 (*f)(); f = 富; F(); Pax,C 编译器也可能会出错。例如 gcc 有“-fleading-underscore”选项。我记得有人告诉我,macosx 用下划线破坏了它的 C 名称。 (我没有macosx,所以我无法检查:))。 Greg,一般都能用,但是不对。函数指针必须是指向具有 C 链接的函数的指针。 extern "C" typedef void funt(); int main() funt * f = foo; F();注意,如果两个函数类型具有差异链接,则它们是不同的——即使它们不是。 无论您将其称为修饰还是名称修饰,事实仍然是 MSVC 上的 __stdcall C 函数从“func”重命名为“_func@12”或类似名称。更多信息在这里:msdn.microsoft.com/en-us/library/zxk0tw93(VS.71).aspx 马丁·约克。不管你怎么称呼它。 mangling 是一个术语,decoration 是另一个术语。两者都更改了目标文件中使用的名称。***有一篇关于它的文章(好吧,在某些地方,它自相矛盾......,但它包含装饰的东西)。我同意 bk1e【参考方案2】:其他方式:
控制汇编代码中使用的名称 (gcc spec.)
您可以通过编写 asm(或 __asm__)指定要在 C 函数或变量的汇编代码中使用的名称声明符后的关键字。确保您选择的汇编器名称不会与任何其他汇编器符号或引用寄存器冲突,这取决于您。
要指定函数的汇编程序名称,请在函数定义之前为函数编写声明,并将 asm 放在那里,如下所示:
int func () asm ("MYFUNC");
int func ()
g++
将编译它,nm -D
输出将是
0000000000001e02 T MYFUNC
而不是
0000000000001e02 T _Z4funcv
在 g++ 4.9.2 上测试
【讨论】:
【参考方案3】:你的意思是你可以从库中导出你的函数?
extern "c" your code here
【讨论】:
【参考方案4】:Schaub 的回答实际上是不正确的。避免名称修改的最常见原因是因为您正在构建一个共享库(在 Windows 上,一个 DLL),该库由您无法控制的需要某些导出函数名称的客户端软件使用。由于编译器之间的重整差异,此类接口历来避免名称重整。
你要做的就是这个。首先,在您的源代码中添加 extern "C"
以摆脱 C++ 修改;尽管如此,这仍然使 C 受到影响。二、编译时使用-Wl,--kill-at
命令行选项。
例子:
extern"C" __declspec(dllexport) hresult __stdcall MyExportedFunction( ... )
....
并编译:
gcc -shared -mwindows -Wl,--kill-at -Werror ... -o MyLib.dll MyLib.cpp -lkernel32 -l...
您可以使用 Dependency Walker 验证您是否正确。
【讨论】:
【参考方案5】:如果你想编译成 wasm,你可以通过 clang -Wl,--demangle
将 --demangle
选项添加到 wasm-ld
链接器
【讨论】:
以上是关于如何避免名称混淆?的主要内容,如果未能解决你的问题,请参考以下文章