5

如何找出将分配给每个方法名称的修饰名称?我试图找出修饰名称是什么,以便我可以在 DLL 中导出它。

4

6 回答 6

7

.DEF 文件仍在使用?

忘记 .DEF 文件。它们已成为过去。

通过 __declspec(dllimport/dllexport) 导出您的函数,无论是 C 函数还是 C++ 符号。

如果您确实需要未修饰的名称,请按照 Greg Hewgill 的建议使用 __declspec(dllimport/dllexport) 关键字,并结合 extern "C",这将去除这些符号的修饰...

您确定要删除 C++ 装饰吗?

这有一些正当的理由:您想要导出 C 代码将使用的代码,或者您想要使用使用不同编译器编译的模块中的 DLL。

由于第二个原因,我会改为为每个编译器生成一个 DLL,并保留装饰。

除了这些原因,你为什么要移除装饰?

C++ 装饰/名称修饰不是邪恶的

恰恰相反。

如果您正在使用一个编译器(我想您这样做了,因为您想使用修饰名称,而不是 extern "C" 的),然后保持 C++ 修饰/名称修饰。

通过这种方式,您将能够使用完整的 C++ 功能,即命名空间、类、函数/方法重载等。

尽管如此,手动使用符号装饰是一种灾难:使用 dllexport 导出符号,而无需处理另一个 (.DEF) 文件。

于 2008-10-10T21:06:26.180 回答
5

这个问题非常相似:Exporting DLL C++ Class , question about .def file。快速总结是您可能希望使用__declspec(dllexport)让编译器为您完成导出方法的工作。

Microsoft 在每个编译器版本中都改变了他们对函数名称进行修改(或称它们为“修饰名称”)的方式,因此如果您尝试手动导出修改后的名称,将来可能会遇到维护问题。如果您在 Google 上搜索“msvc 修饰名称”,则有一些链接可能会有所帮助,但不能保证。

于 2008-10-10T06:39:32.433 回答
2

由于 C++ 名称修改不是在不同编译器之间匹配的东西(正如Greg Hewgill提到的,它甚至可以在同一供应商的编译器的版本之间更改)并且 C++ 没有标准的二进制接口,因此导出 C++ 通常不是一个好主意DLL 中的函数。如果 DLL 非常紧密地绑定到使用它的应用程序并对其进行版本控制,则例外情况。

另一种方法是将导出的函数声明为extern "C".

于 2008-10-10T06:50:56.543 回答
2

通过在对象文件上使用dumpbin ,您会发现对象中使用的所有方法。这是它的使用方法

dumpbin /symbols File.obj
于 2008-10-17T19:32:59.173 回答
0

我认为您应该听取前面 2位受访者 Greg HewgillMike B的建议,但是如果您使用的是 Microsoft 工具链并且您真的想知道修饰名称...

  1. 使用__declspec(dllexport)创建您的 .lib 和 .dll 文件
  2. 使用 dumpbin /exports 检查 dll 导出的名称
  3. 现在您可以删除__declspec(dllexport)并在.def文件中手动导出符号
于 2008-10-10T15:39:45.403 回答
0

在 VS2005 中,有一个预处理器宏funcdname,当放置在函数中时,它返回一个带有修饰名称的字符串。然而,这是非标准的——C99 标准对此有func,我不能说你的编译器是否支持它。

(为什么下划线不能正确显示??)

(编辑:)这显然是最近在类似的讨论中出现的。

于 2009-05-01T18:43:27.773 回答