[英]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;
}
我可以确保hGetProcIDDLL
和func_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。
有关LoadLibrary
和GetProcAddress
用法的注释; 如果您需要动态加载dll,则需要获取绑定到导出函数的C ++类成员函数。 我还没有看到成功的实现,或者甚至没有合理的可能。 如果需要使用LoadLibrary
和GetProcAddress
,请考虑使用抽象类,并在某种工厂中创建对象。
您没有详细说明动态加载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.