在def文件中导出修饰函数名

Visual C++: Exporting decorated function name in a def file

本文关键字:函数 def 文件      更新时间:2023-10-16

我想在def文件中导出一个修饰过的函数名:

LIBRARY Example
EXPORTS
??0__non_rtti_object@std@@QAE@ABV01@@Z=myfunc @1

问题是链接器在第一个@-符号处去掉了函数名,只放置了"? ?0__non_rtti_object"导入到导出表中。我现在的问题是,是否有办法把还有@-字符?我使用Visual Studio 2010。也许有人能帮我。

提前谢谢你,汉内斯。

引言

您没有回答我关于使用. def文件的评论,所以我认为您一定不熟悉dllexportdllimport限定符。有了它们,就不需要. def文件来导出符号了。

如果特别需要. def文件使dllimport/dllexport特性的使用无效,请忽略以下内容。

如何使用dllimport/dllexport ?

在您的公共标头(例如public.hpp)中,编写如下内容:

#ifdef MY_PROJECT_EXPORTS
   #define MY_PROJECT_API __declspec(dllexport)
#else
   #define MY_PROJECT_API __declspec(dllimport)
#endif

这样,宏MY_PROJECT_API将启用符号的导出/导入。例如,稍后,在同一个public.hpp中,您可以声明:

// A global variable
MY_PROJECT_API int myGlobalVariable ;
// A function
MY_PROJECT_API void my_function() ;
// A class or struct
class MY_PROJECT_API MyClass
{
   public :
      int i;
      virtual int foo() ;
      // etc.
} ;

然后,你需要做的是,在你的库的项目选项中,定义MY_PROJECT_EXPORTS:这样,当你编译你的库时,上面的符号被声明为dllexport,当别人包含你的public.hpp头文件时,上面的符号将被声明为dllimport

如果你的代码是跨平台的(dllimport/dllexport是一个MS编译器的特性),只需将上面的定义包装在编译器测试中。例如:

#ifdef _MSC_VER
   // For MS Visual Studio
   #ifdef MY_PROJECT_EXPORTS
      #define MY_PROJECT_API __declspec(dllexport)
   #else
      #define MY_PROJECT_API __declspec(dllimport)
   #endif
#else
   // For other compilers
   #define MY_PROJECT_API
#endif

关于.DEF文件?

. def文件是在之前使用的,当时可导出的C函数在Visual Studio上仍然是"主流"。

为了强类型安全,c++修饰了符号。

缺点是每个编译器都有自己的装饰方案(这在12年的开发中从来没有困扰过我),并且找到一个符号的确切的装饰名称不会很痛苦。

但这样做的优点是:

  1. 现在可以导出重载/命名空间函数/符号
  2. 参数类型是ABI的一部分,这意味着链接器可以验证你没有搞砸或欺骗你的类型

dllimportdllexport特性具有以下优点:

  1. 它使导出在源级完成,而不是使用另一个项目文件
  2. 程序员现在可以忽略特定的装饰方案(通常只对链接器感兴趣),同时从扩展到链接器的c++的强类型安全中获益。

来源

有关更多信息,请参见:

  • __declspec: http://msdn.microsoft.com/en-us/library/dabb5z75.aspx
  • dllexport, dllimport: http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx
  • 在c++类中使用dllimportdllexport: http://msdn.microsoft.com/en-us/library/81h27t8c.aspx