【发布时间】:2010-09-16 11:04:30
【问题描述】:
如何找出将分配给每个方法名称的修饰名称?我正在尝试找出修饰名称是什么,以便我可以将其导出到 DLL 中。
【问题讨论】:
标签: c++ dll export name-mangling
如何找出将分配给每个方法名称的修饰名称?我正在尝试找出修饰名称是什么,以便我可以将其导出到 DLL 中。
【问题讨论】:
标签: c++ dll export name-mangling
忘记 .DEF 文件。它们已成为过去。
通过 __declspec(dllimport/dllexport) 导出您的函数,无论是 C 函数还是 C++ 符号。
如果您确实需要未修饰的名称,请按照 Greg Hewgill 的建议使用 __declspec(dllimport/dllexport) 关键字,结合 extern "C",这将去除这些符号的修饰...
这有一些正当的理由:您想导出将由 C 代码使用的代码,或者您想使用使用不同编译器编译的模块中的 DLL。
出于第二个原因,我会改为为每个编译器生成一个 DLL,并保留装饰。
除了这些原因,你为什么要移除装饰?
恰恰相反。
如果您正在使用一个编译器(我想您会这样做,因为您想使用修饰名称,而不是 extern "C" 的名称),然后保持 C++ 修饰/名称修饰。
通过这种方式,您将能够使用完整的 C++ 功能,即命名空间、类、函数/方法重载等。
不过,手动使用符号装饰是一种灾难:使用 dllexport 导出符号,而无需处理另一个 (.DEF) 文件。
【讨论】:
这个问题非常相似:Exporting DLL C++ Class , question about .def file。简要总结一下,您可能希望使用__declspec(dllexport) 让编译器为您完成导出方法的工作。
Microsoft 会在每个编译器版本中更改他们对函数名称进行修改(或称为“修饰名称”)的方式,因此如果您尝试手动导出修改后的名称,将来可能会遇到维护问题。如果您在 Google 上搜索“msvc 修饰名称”,那么有些链接可能会有所帮助,但不能保证。
【讨论】:
由于 C++ 名称修饰不是在不同编译器之间匹配的东西(正如 Greg Hewgill 提到的,它甚至可以在同一供应商的编译器的版本之间改变)并且 C++ 没有标准的二进制接口,它通常不是一个好的从 DLL 导出 C++ 函数的想法。如果 DLL 非常紧密地绑定到使用它的应用程序并对其进行版本控制,则例外情况。
另一种方法是将导出的函数声明为extern "C"。
【讨论】:
通过在对象文件上使用dumpbin,您将找到对象中使用的所有方法。这是它的使用方法
dumpbin /symbols File.obj
【讨论】:
我认为你应该听取前面两位回复者Greg Hewgill和Mike B的建议,但是如果你使用的是微软工具链并且你真的很想知道修饰名...
【讨论】:
在 VS2005 中,有一个预处理器宏 FUNCDNAME,当放置在函数中时,它会返回一个带有修饰名称的字符串。然而,这是非标准的——C99 标准对此有 func,我不能说你的编译器是否支持。
(为什么下划线不能正确显示??)
(编辑:)这显然是最近在similar discussion 中出现的。
【讨论】: