我正在学习如何构建DLL并从另一个项目中调用它(我也希望DLL不仅可以通过C / C ++调用,还可以通过Python调用)。这是我构建DLL的代码:
callbacktesetDLL.h:
#ifdef CALLBACKTESTDLL_EXPORTS
#define CALLBACKTESTDLL_API __declspec(dllexport)
#else
#define CALLBACKTESTDLL_API __declspec(dllimport)
#endif
typedef int(CALLBACK *p)(char*);
CALLBACKTESTDLL_API int __stdcall StrToInt(char*);
CALLBACKTESTDLL_API char* __stdcall NumCompare(p FuncP, char*, int b);
callbacktestDLL.cpp:
#include "stdafx.h"
#include <stdio.h>
#include "callbacktestDLL.h"
#include <stdlib.h>
CALLBACKTESTDLL_API int __stdcall StrToInt(char* StrInput)
{
int IntResult;
IntResult = atoi(StrInput);
return IntResult;
}
CALLBACKTESTDLL_API char* __stdcall NumCompare(p FuncP, char* StrInput, int b)
{
int a = FuncP(StrInput);
if (a>b)
{
return "a is bigger than b";
}
else
{
return "b is bigger than a";
}
}
和Source.def文件:
LIBRARY
EXPORTS
StrToInt @1
NumCompare @2
根据上面的代码,我得到callbacktestDLL.dll
和callbacktestDLL.lib
。 依赖,功能&#39;可以显示DLL中的名称:
现在我想从另一个项目中调用DLL中的函数:
CallDLL.h:
#pragma comment(lib,"callbacktestDLL.lib")
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
typedef int(*p)(char*);
extern "C" _declspec(dllimport) int StrToInt(char* InpuString);
extern "C" _declspec(dllimport) char* NumCompare(p FuncP, char*, int b);
CallDLL.cpp:
#include "stdafx.h"
int main()
{
p FuncP_R = StrToInt;
NumCompare(FuncP_R, "1234", 40);
return 0;
}
但是,当我运行该项目时,它告诉我:error LNK2019: unresolved external symbol __imp__StrToInt
和error LNK2019: unresolved external symbol __imp__NumCompare
。我已经将.lib
和.dll
文件复制到CallDLL项目的根文件夹下。为什么会这样?我该如何解决?谢谢你的关注。
答案 0 :(得分:0)
我终于做到了。这是详细信息: 生成DLL的文件:
<强> callbacktestDLL.h:强>
typedef int(CALLBACK *p)(char*);
extern "C" __declspec(dllexport) int __stdcall StrToInt(char* InputString);
extern "C" __declspec(dllexport) char* __stdcall NumCompare(p FuncP, char* InputString, int b);
<强> callbacktestDLL.cpp:强>
#include "stdafx.h"
#include <stdio.h>
#include "callbacktestDLL.h"
#include <stdlib.h>
extern "C" CALLBACKTESTDLL_API int __stdcall StrToInt(char* InputString)
{
int IntResult;
IntResult = atoi(InputString);
return IntResult;
}
extern "C" __declspec(dllexport) char* __stdcall NumCompare(p FuncP, char* InputString, int b)
{
int a = FuncP(InputString);
if (a>b)
{
return "a is bigger than b\n";
}
else
{
return "b is bigger than a\n";
}
}
与帖子中的前一个文件相比,我删除了.def
文件,并在每个函数声明和定义之前添加了extern "C"
。然后我生成一个新的.dll和.lib文件,并将它们复制到CallDLL
项目&#39;根文件夹。我使用depends
来查看功能&#39; DLL中的名称:
我还改变了CallDLL的文件:
<强> CallDLL.h:强>
#pragma comment(lib,"callbacktestDLL")
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
typedef int(__stdcall *p)(char*); //same as typedef int(CALLBACK *p)(char*) in callbacktestDLL.h
extern "C" _declspec(dllimport) int __stdcall StrToInt(char* InputString); //exactly same as what's in callbacktestDLL.h apart from dllimport
extern "C" _declspec(dllimport) char* __stdcall NumCompare(p FuncP, char* InputString, int b); //exactly same as what's in callbacktestDLL.h apart from dllimport
<强> CallDLL.cpp:强>
#include "stdafx.h"
int main()
{
p FuncP_R;
char* a = "1234";
FuncP_R = StrToInt;
printf(NumCompare(FuncP_R, a, 42));
return 0;
}
它按预期工作。我认为我犯的一个错误是在导入时丢失__stdcall
。也许有关于名称错误的错误。我会继续测试它。
答案 1 :(得分:0)
您应始终包含相同的头文件以定义一致的界面。创建不同的头文件很容易出错。接口的下一次更改可能会使接口不兼容。
实现函数的模块与使用这些函数的模块之间存在细微差别。区别在于__declspec(dllimport)
或__declspec(dllexport)
。这就是头文件包含
# ifdef CALLBACKTESTDLL_EXPORTS
实现这些功能的模块也会导出它们。因此,您必须在项目设置中定义符号。如果在命令行编译,则必须将/D CALLBACKTESTDLL_EXPORT
添加到编译器参数。
顺便说一句:如果您已定义CALLBACKTESTDLL_EXPORT
,则您的CALLBACKTESTDLL_API
宏包含__declspec(dllexport)
。这会导致链接器创建DLL导出表。 .DEF
不是必需的。你应该删除它,因为.....它再次定义了界面(在不同的级别)。