c++ - 链接器未解析的外部符号 - 在 dll 中找不到函数

标签 c++ dll linker-errors lnk2019

我在 Visual Studio C++ 中工作。

我做了一个非静态函数的类,打包成一个dll。这是生成我的 dll 的代码:

// head file
#ifndef FUNCTIONS_H_
#define FUNCTIONS_H_

#include <string>
#include <memory>

#ifdef MATHFUNCSDLL_EXPORTS
#define MATHFUNCSDLL_API __declspec(dllexport) 
#else
#define MATHFUNCSDLL_API __declspec(dllimport) 
#endif

MATHFUNCSDLL_API class Functions
{
public:
    MATHFUNCSDLL_API void func(int, std::string);
};


extern "C" MATHFUNCSDLL_API Functions * __cdecl create_class();

#endif


// cpp file
#include "stdafx.h"
#include "Functions.h"
#include <iostream>

void Functions::func(int id, std::string name)
{
    std::cout << "Your ID: " << id << ". Your name: " << name << std::endl;
}

Functions * create_class()
{
    std::cout << __FUNCTION__ << std::endl;
    return new Functions();
}

现在我有一个动态加载此 dll 的 C++ 项目。这是代码:

#include <iostream>
#include <Windows.h>
#include "../../testDmcDLL/testDmcDLL/Functions.h"
typedef Functions *(__stdcall *f_funci)();
int main(int argc, char ** argv)
{
    HINSTANCE hGetProcIDDLL = LoadLibrary("C:\\Documents\\Visual Studio 2013\\Projects\\testDmcDLL\\Debug\\testDmcDLL.dll");
    f_funci func_create_class = (f_funci)GetProcAddress(hGetProcIDDLL, "create_class");
    Functions * pf = func_create_class();
    ////LNK error////pf->func(1, "toto");
    system("pause");
    return 0;
}

我可以确定 hGetProcIDDLLfunc_create_class已成功初始化(我用 if 测试了它们,但在这里我删除了 if )。

当我运行这个项目时,我可以看到 create_class显示在控制台上,因为有 std::cout << __FUNCTION__ << std::endl;在那个函数中。所以一切看起来都很好。

但是,当我用代码编译它时 pf->func(1, "toto")未注释,我收到链接器 (LNK2019) 错误:

Error 1 error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall Functions::func(int,class std::basic_string,class std::allocator >)" (__imp_?func@Functions@@QAEXHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function _main c:\documents\visual studio 2013\Projects\testLoadDmcDLL\testLoadDmcDLL\main.obj testLoadDmcDLL

最佳答案

导出的类定义不太对,应该是这样的形式;

class MATHFUNCSDLL_API Functions // MATHFUNCSDLL_API moved
{
public:
    void func(int, std::string); // MATHFUNCSDLL_API removed
};

导出类后,将导出其所有成员。

您没有提到编译期间如何定义 MATHFUNCSDLL_EXPORTS(从命令行或可能在 stdafx.h 中),但请确保在构建 dll 时定义它,而不是在构建时定义它执行文件。请务必链接到由 .dll 生成的 .lib。


关于 LoadLibraryGetProcAddress 用法的注释;如果需要动态加载dll,则需要获取绑定(bind)到导出函数的C++类成员函数。我还没有看到这个的成功实现,或者它是否合理。如果需要使用 LoadLibraryGetProcAddress,请考虑使用抽象类并在某种工厂中创建对象。

你没有详细说明动态加载dll的动机,但也可以考虑延迟加载dll。

如果动机是延迟加载 dll,但始终使用同一个 dll,那么延迟加载链接可能会有所帮助。如果动机是根据某些运行时参数(或配置)加载未知的 dll(按名称/位置),那么虚拟基类和单个 C 风格函数作为对象的工厂可能是首选解决方案。

有一个good code project关于此的文章描述了为此的各种解决方案。特别是使用 abstract base class非常便携。

关于c++ - 链接器未解析的外部符号 - 在 dll 中找不到函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33564577/

相关文章:

C++模板化接口(interface)

c++ - 使用VS2005编译时静态库文件巨大,使用gcc编译时正常大小

c++ - 使用 `strcpy` 删除二维数组中的一行(字符)时是否有任何错误?

c++ - 无法在 Windows 中运行 Qt 应用程序

c# - VBA C# DLL 未注册

c++ - 从临时的赋值和引用初始化

delphi - 我们可以在运行时使用dcu(Delphi编译单元)吗?

ios - xcode 5 ld : 11 duplicate symbols for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation)

iphone - 找不到 i386 架构的 Facebook 符号

iOS - 架构 i386 的 3 个重复符号