我有一个dll,它访问项目之外的一些类(我使用Visual Studio,所以我有两个项目)。问题是,在dll包含的标题中,在dll的项目之外,只有函数体,如下所示:
x.h
class x
{
void myFunc();
}
在另一个cpp文件中,在dll文件之外:
#include "x.h"
x::myFunc()
{
//.....
}
dll只获取函数的主体,所以当我编译时,我会得到许多未解析的外部符号(我很确定这是问题,因为我测试了另一个完全内置在.h文件中的类,另一个项目,没有错误)。那么我该如何解开这个谜团呢?
导入标题只有函数签名是正常的;实际的函数体已经编译成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的构造。其他编译器/运行时以不同方式处理符号导出。
有多种方法可以将DLL链接到Windows上的应用程序,请查看现有的问题/答案:https://stackoverflow.com/a/2060508/1701823