【问题标题】:Is there a way to suppress c++ name mangling?有没有办法抑制 c++ 名称修改?
【发布时间】:2010-10-28 11:56:35
【问题描述】:

我有一个用 C++ 编写的 DLL,我想抑制一些导出方法的名称修改。这些方法是全局的,不是任何类的成员。有没有办法做到这一点?

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

【问题讨论】:

  • 我认为这是一个骗局:stackoverflow.com/questions/524633/…
  • 不完全是 dup IMO:我们在这里说的是导出的 DLL 函数,它为游戏带来了完全不同的解决方案。

标签: c++ visual-studio winapi name-mangling


【解决方案1】:

用 extern "C" {}包围函数定义

extern "C" {
    void foo() {}
}

http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html

【讨论】:

  • 你需要声明和定义都是 extern "C"ed,对吧?
  • @leander 不,只要声明就足够了;只要声明包含在定义点并且签名完全匹配,“C”-ness 就会自动应用于定义。你可以把它放在两者上,如果,例如,参数不完全匹配,你会得到一个错误(VS中的C2733)而不是错误的版本被静默导出。
【解决方案2】:

您可以使用带有 EXPORTS 部分的 .def 文件来避免导出函数的所有修改(C++、cdecl、stdcall...)。只需创建一个 MyDll.def 文件并将其添加到您的项目中:

LIBRARY "MyDLL"
EXPORTS
  Foo
  Bar

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

【讨论】:

    【解决方案3】:

    "bradtgmurray" 是对的,但是对于 Visual C++ 编译器,无论如何您都需要显式导出您的函数。但是使用“Serge - appTranslator”建议的 .DEF 文件是错误的方法。

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

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

    因此,在 Visual C++ 中导出未修饰函数的正确方法是将导出“C”习语(如“bradtgmurray”回答)与 dllimport/dllexport 关键字结合起来。

    一个例子?

    例如,我在 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 文件或外部“C”在这里没有帮助。
    • @ajay :我无法帮助您发表评论。您可以做的是使用 Visual Studio 生成带有示例符号的 DLL,以查看它是如何完成的。如果您仍然卡住,您应该在 StackOverflow(或 CodeReview?)上发布(有限版本)您的代码,包括 DLL 代码(标题、源代码)、链接到它的 EXE 代码(源代码),和错误信息。您的错误可能来自错误的构造函数重载调用:如果您尝试从 DLL 内部调用相同的构造函数,是否会出现错误?如果是,那么您需要声明/定义正确的构造函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 2013-12-13
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    相关资源
    最近更新 更多