代码之家  ›  专栏  ›  技术社区  ›  Amir-Mousavi

c++dll函数导出命名约定(mangling)

  •  0
  • Amir-Mousavi  · 技术社区  · 6 年前

    我是全新的C++,并从创建一个简单的DLL和控制台应用程序开始测试 dll . 这个 动态链接库 之后的插件应该在x86机器上工作(诊断工具、ECU或PLC)。提供给我的示例是,我使用与sdcall相同的结构导出dll函数。所以我的地狱世界计划看起来像:

    plugin.dll
    -----------
    plugin.h
    #pragma once
    #include "types.h"
    #define EXPORT extern "C" __declspec (dllexport)
    EXPORT S32 WINAPI Greetings(string *str);
    
    plugin.cpp
    #include "plugin.h"
    #include "types.h"
    S32 __stdcall Greetings(string *str){*str = "Hello From Plugin!"; return -1;}
    

    控制台应用程序看起来像:(两者都在同一个解决方案中, project/properties/cc++/adnvances/callingConvention = __cdecl (/Gd) )

    VS设置-解决方案配置=调试,解决方案平台=x86

    main.cpp
    HMODULE DllHandler = ::LoadLibrary(L"plugin.dll");
    string greetingText;
    typedef U32(*Type)(string*);
    Type greetings = reinterpret_cast<Type>(GetProcAddress(DllHandler, "Greetings"));
    greetings(&greetingText);
    cout << greetingText << endl;
    

    现在,没有 plugin.def 这个 GetProcAddress(DllHandler, "Greetings") 使用plugin.def(连同EXPORT)返回null(0x000000),我得到 Greetings 带装饰 plugin.dll!Greetings@4 电话会成功的,但是

    运行时检查失败#0-ESP的值未通过函数调用正确保存。这通常是调用使用一个调用约定声明的函数以及使用另一个调用约定声明的函数指针的结果。

    也不允许使用命名约定进行强制转换。 我发了很多帖子 __cdecl __stdcall 但主要是解释清理堆栈的程序集级别,或者使用 .def extern "C" 有出口。

    我在命名约定和C++中完全迷失了方向。是否与本地项目设置相关,或者dll将在所有环境中运行?特别是在这个示例项目中,我应该如何处理它?

    0 回复  |  直到 6 年前