繁体   English   中英

链接器无法解析的外部符号-找不到DLL中的函数

[英]Linker unresolved external symbols - can't find functions in dll

我在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();
}

现在,我有一个C ++项目,可以动态加载该dll。 这是代码:

#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)错误:

错误1错误LNK2019:无法解析的外部符号“ __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)在函数_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
};

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

您没有提到在编译过程中(从命令行或可能在stdafx.h中)如何定义MATHFUNCSDLL_EXPORTS ,但是请确保在构建dll时定义了它,但在构建exe时没有定义。 确保链接使用.dll生成的.lib。


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

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

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

关于此的一篇很好的代码项目文章描述了各种解决方案。 特别是使用抽象基类是非常可移植的。

如果您不依赖导入库,而是调用GetProcAddress ,则需要对要导入的每个函数执行此操作。 您从未为__imp_?func@Functions@@QAEXHV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z调用GetProcAddress (这就是您的Functions::func在DLL中被破坏了。

另外,请注意,您从GetProcAddress获得函数指针。 尽管这指向实现pf->func的代码,但没有使用成员函数调用语法来调用函数指针。

根本问题是GetProcAddress实际上是为C设计的,而不是C ++设计的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM