C++ dll 和名称修改问题

C++ dll and name mangling issue

我正在尝试一个简单的测试 DLL 项目。在我的解决方案下,我有两个项目——第一个 C++ Dll(库)和第二个 C++ exe(驱动程序)。下面我附上了基本项目设置的快照:

dllmain.h

#ifndef DLLMAIN_H_
#define DLLMAIN_H_

#ifdef FFMPEGLIB_EXPORTS
#define FFMPEGLIB_API __declspec(dllexport)
#else
#define FFMPEGLIB_API __declspec(dllimport)
#endif // FFMPEGLIB_EXPORTS

static void TestFoo();

extern "C" FFMPEGLIB_API void Test(int* num);

extern "C" FFMPEGLIB_API void ProxyFoo();

#endif

dllmain.cpp

#include "dllmain.h"
#include "A.h"

void TestFoo()
{
    A a;
    a.foo();
}

void Test(int* num)
{
    *num = *num + 1;
}

void ProxyFoo()
{
    TestFoo();
}

driver.cpp

#include <iostream>

#include "dllmain.h"

int main(int argc, char** argv)
{
    int mum  = 4;
    Test(&num);

    std::cout << num;

    ProxyFoo();

    return 0;
}

库项目编译正常,但exe编译失败,链接错误:

Code        Description                                 Project     File
LNK2001     unresolved extern symbol _imp_ProxyFoo      driver      driver.obj
LNK2001     unresolved extern symbol _imp_Test          driver      driver.obj
LNK1120     2 unresolved externals                      driver      driver.exe

我这里有两个问题:

  1. 为什么 dllmain.h 的函数名尽管被标记为 extern "C" 但还是被破坏了?

  2. 为什么我不能从 extern 方法创建测试 class A 的实例?这样做的好方法是什么?

您需要将 extern "C" 放在您打算在 dllmain.cpp 中导出的函数定义周围,以便它与您声明的链接相匹配。

此外,您还需要做 declexport 事情。

extern "C"
{
    __declspec(dllexport) void Test(int* num)
    {
       *num = *num + 1;
    }

    __declspec(dllexport) void ProxyFoo()
    {
        TestFoo();
    }
}

Why the function name of dllmain.h getting mangled in spite being marked as extern "C"?

因为__declspec(dllimport).

Why can I not create instance of test class A from extern methods? What would be good way of doing it?

我觉得没问题,但您没有提供任何 class A 代码。只需这样做:

class __declspec(dllexport) A
{
    /* ... */
};

Why EXE compile failed?

这是因为你没有将DLL的LIB文件导入到项目中

有两种导入方式:

  1. #program comment(lib, "<YOUR_LIB_FILE>.lib") 添加到代码文件。
  2. <YOUR_LIB_FILE>.lib 添加到属性 -> 链接器 -> 输入 -> 附加依赖项。

微软文档:https://docs.microsoft.com/en-us/cpp/build/importing-and-exporting