1

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

xh

class x
{
    void myFunc();
}

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

#include "x.h"

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

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

4

2 回答 2

1

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

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

编辑:下一步是确保二进制文件实际上正在导出您尝试链接的符号。确保所有接口签名都通过__declspec(dll_export) 前缀导出。通常,这包含在 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 的结构。其他编译器/运行时以不同方式处理符号导出。

于 2012-11-01T23:01:17.767 回答
1

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

于 2012-11-01T23:08:57.897 回答