有没有一种方法可以抑制C++的名称修饰?

6

我有一个用C++编写的DLL,我想为一些导出的方法禁止名称修饰。这些方法是全局的,不属于任何类。有没有办法实现这个目的?

顺便说一下:我正在使用VS2008。


3
我认为这是一个重复的问题:https://dev59.com/oXRB5IYBdhLWcg3wv5tA - Johannes Schaub - litb
2
不完全相同,在这里我们谈论的是导出的DLL函数,这将为游戏带来完全不同的解决方案。 - Serge Wautier
3个回答

26

1
你需要将声明和定义都加上 extern "C" 吗? - leander
1
@leander 不需要,只有声明就足够了;只要在定义的地方包含了声明并且签名完全匹配,"C"特性将自动应用于定义。你可以在两个地方都放置它,如果参数不完全匹配,你将会得到一个错误(在VS中是C2733),而不是错误版本被静默导出。 - Tim Sylvester

11

"bradtgmurray"说的没错,但对于Visual C++编译器,你仍然需要显式地导出你的函数。但是使用像“Serge - appTranslator”建议的.DEF文件是不正确的方法。

在Visual C ++上导出符号的通用方法是什么?

使用declspec(dllexport/dllimport)指令,它适用于C和C ++代码,无论是否装饰过(而.DEF仅限于C,除非您想手动装饰代码)。

因此,在Visual C++中导出未装饰的函数的正确方法是将导出“C”习语与dllimport/dllexport关键字相结合,就像“bradtgmurray”所回答的那样。

一个例子?

例如,在Visual C++上创建了一个空的DLL项目,并编写了两个函数,一个被称为CPP,因为它已被装饰,另一个是C,因为它没有被装饰。 代码如下:

// Exported header
#ifdef MY_DLL_EXPORTS
#define MY_DLL_API __declspec(dllexport)
#else
#define MY_DLL_API __declspec(dllimport)
#endif

// Decorated function export : ?myCppFunction@@YAHF@Z
MY_DLL_API int myCppFunction(short v) ;

// Undecorated function export : myCFunction
extern "C"
{
MY_DLL_API int myCFunction(short v) ;
} ;

我猜您已经知道,但为了完整起见,MY_DLL_API宏应该在DLL makefile(即VCPROJ)中定义,而不是由DLL用户定义。

C ++代码很容易编写,但为了完整起见,我将在下面编写它:

// Decorated function code
MY_DLL_API int myCppFunction(short v)
{
   return 42 * v ;
}

extern "C"
{

// Undecorated function code
MY_DLL_API int myCFunction(short v)
{
   return 42 * v ;
}

} ;

我正在创建一个显式 DLL 中的类。调用此类的构造函数会生成错误“未解析的外部符号...”。我猜这是由于名称混淆导致的。请写出如何避免这个问题。DEF 文件或 extern "C" 在这里没有帮助。 - null
@ajay:我无法在评论中帮助你。你可以使用Visual Studio生成一个带有示例符号的DLL来查看如何完成此操作。如果你仍然卡住了,你应该在StackOverflow(或CodeReview?)上发布(限制版本的)代码,包括DLL代码(头文件、源代码)、链接到它的EXE代码(源代码)和错误消息。可能你的错误来自于错误的构造函数重载调用:如果你尝试从DLL内部调用相同的构造函数会出现错误吗?如果是,那么你需要声明/定义正确的构造函数。 - paercebal

11

你可以通过在项目中添加一个包含 EXPORTS 部分的 .def 文件来避免所有对导出函数的编译器修饰(如 C++、cdecl、stdcall 等)。只需创建一个名为 MyDll.def 的文件并将其添加到您的项目中:

LIBRARY "MyDLL"
EXPORTS
  Foo
  Bar

实际上,向导很可能已经为您创建了一个def文件。您只需要填写EXPORTS部分即可。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接