如何修复C ++ DLL中的Unresolved External Symbol错误?

问题描述 投票:1回答:2

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

x.h

class x
{
    void myFunc();
}

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

#include "x.h"

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

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

c++ function dll scope unresolved-external
2个回答
1
投票

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

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

编辑:下一步是确保二进制文件实际导出您尝试链接的符号。确保通过__declspec(dll_export) prefixes导出所有界面签名。通常,这将包含在IFDEF中,以便在编译DLL时声明导出头,但在客户端项目中包含该头时则不会。接下来,您可以使用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标记您的公共API函数,并且它们应该在构建期间导出。

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


1
投票

有多种方法可以将DLL链接到Windows上的应用程序,请查看现有的问题/答案:https://stackoverflow.com/a/2060508/1701823

© www.soinside.com 2019 - 2024. All rights reserved.