导入标头只有函数签名是正常的;实际的函数体已经编译到 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 的结构。其他编译器/运行时以不同方式处理符号导出。