从DLL

时间:2018-05-30 07:47:23

标签: c++ dll

我正在学习如何构建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.dllcallbacktestDLL.lib依赖,功能&#39;可以显示DLL中的名称: enter image description here

现在我想从另一个项目中调用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__StrToInterror LNK2019: unresolved external symbol __imp__NumCompare。我已经将.lib.dll文件复制到CallDLL项目的根文件夹下。为什么会这样?我该如何解决?谢谢你的关注。

2 个答案:

答案 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中的名称: enter image description here

我还改变了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不是必需的。你应该删除它,因为.....它再次定义了界面(在不同的级别)。