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

时间:2012-11-01 22:55:51

标签: c++ function dll scope unresolved-external

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

x.h

class x
{
    void myFunc();
}

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

#include "x.h"

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

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

2 个答案:

答案 0 :(得分: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 :(得分:1)

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