c++ - 如何修复 C++ DLL 中未解析的外部符号错误?

标签 c++ function dll scope unresolved-external

我有一个 dll,它访问其项目之外的一些类(我使用的是 Visual Studio,所以我有两个项目)。问题是,在 dll 包含的 header 中,在 dll 的项目之外,只有函数体,如下所示:

x.h

class x
{
    void myFunc();
}

在 dll 文件之外的另一个 cpp 文件中:

#include "x.h"

x::myFunc()
{
    //.....
}

dll 只获取函数体,所以当我编译时,我得到很多未解析的外部符号(我很确定这是问题所在,因为我用另一个完全内置在 .h 中的类进行了测试文件,在另一个项目中,没有错误)。那么我该如何解开这个谜呢?

最佳答案

导入头文件只有函数签名是正常的;实际的函数体已经编译到 DLL 二进制文件中,并在链接时通过链接到实际的 DLL 中进行解析。

首先要尝试的是确保您确实链接到所述 DLL。仅仅包含 header 是不够的,您还需要链接到二进制文件。因此,在您的项目配置中,您需要添加一个指向(例如)编译 DLL 时与 DLL 一起创建的 .lib 文件的链接(如果在 MSVC 中)。这个 lib 文件让链接器知道如何将您通过导入 header 包含的函数签名连接到 DLL 中包含的实际实现。如果您在不同的平台上,机制可能会略有不同,但概念会相似。

编辑: 下一步是确保二进制文件确实导出了您尝试链接的符号。确保所有接口(interface)签名都通过 __declspec(dll_export) prefixes 导出.通常这会包含在 IFDEF 中,以便在编译 DLL 时 header 被声明为导出,但当该 header 包含在客户端项目中时则不会。接下来,您可以使用 dumpbin 检查损坏的导出名称,看看是否有任何意外。

这是您的示例的修改版本,它说明了这种导出方式(请注意,我还没有测试过它是否可以编译,对于任何错别字我深表歉意):

#ifdef BUILDING_MYDLL
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

class MYDLL_API x
{
    void myFunc();
}

然后您可以将配置设置为在编译 dll 时定义 BUILDING_MYDLL,但在编译可执行文件时则不定义。这样,函数仅在编译库 dll 时才被标记为导出。现在您可以使用 MYDLL_API 标记您的公共(public) API 函数,它们应该在构建期间导出。

请注意,dll_export、dll_import 和 declspec 都是 MSVC 特有的结构。其他编译器/运行时以不同方式处理符号导出。

关于c++ - 如何修复 C++ DLL 中未解析的外部符号错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13186755/

相关文章:

c++ - C/C++,将一个小的 float 截断为2个有意义的数字并用科学的方式表达

c++ - 模板继承类派生基赋值

function - 使用 OUT 参数从函数返回一个列表

c++ - 在 C++ 中调用指向成员函数的指针时出错

ASM x86 FASM 中的函数参数

c++ - 使用远程线程的 DLL 注入(inject)在执行时不执行任何操作

c++ dynamic_cast 错误处理

c++ - 如何编写在源后添加库的makefile

c++ - Windows 上 DLL Exporting/Importing 和 Extern 的问题

c# - 如何干净地停止运行 matlab dll 函数的 .NET 线程