C++ 之 函数封装DLL给C++调用的两种方式
1、打开VS,新建一个动态链接库(DLL)项目,具体如下图

2、编写代码,封装一个接口函数进行调用测试,代码和代码说明如下图

3、代码内容如下:
#include "stdafx.h"
#include <iostream>
using namespace std;
extern "C" __declspec(dllexport) int Sub(int a, int b) {
cout << "调用 DLL 库中的函数...\n";
return a - b;
}
4、点击 生成 dll包,失败 0 个,打包成功,即可在对应路径找到生成的dll 包,具体如下图



5、在新建一个控制台应用,用来测试调用刚才打包 dll 的接口函数,具体如下图

6、然后打开新建的控制台的项目,把打包好的dll,添加进工程中,具体如下图


7、第一种方式:
需要添加对应的lib库目录,在属性管理器中添加对应的dll打包的库目录路径,具体如下图


8、在main函数中声名接口函数,然后调用,生命时可能会有警告,可以忽略,具体如下图

9、脚本具体内容如下:
#include "pch.h"
#include <iostream>
// 添加刚才的文件库
#pragma comment(lib,"DllForCpp.lib")
extern "C" _declspec(dllimport) int Sub(int a,int b);
int main()
{
// 调用测试函数,并打印结果
std::cout<<"10 - 6 = "<< Sub(10,6) << std::endl;
}
10、调试运行,即可看到调用成功,具体如下图


11、第二种方式:
使用反射,引入头文件windows.h,注释掉之前的代码,清理工程,可以把之前添加的库目录去掉,使用反射获取 dll 中的函数,具体如下图

12、脚本的具体内容如下:
#include "pch.h"
#include <iostream>
#include <windows.h>
// 添加刚才的文件库
//#pragma comment(lib,"DllForCpp.lib")
//extern "C" _declspec(dllimport) int Sub(int a,int b);
int main()
{
// 调用测试函数,并打印结果
//std::cout<<"10 - 6 = "<< Sub(10,6) << std::endl;
// 第二方法,不需要添加lib库目录,而是使用反射获取dll中的方法
typedef int(*ptrSub)(int, int);
HMODULE hMod = LoadLibrary("DllForCpp.dll");
if (hMod != NULL) {
ptrSub Sub = (ptrSub)GetProcAddress(hMod, "Sub");
if (Sub != NULL) {
std::cout << "10 - 6 = " << Sub(10, 6) << std::endl;
}
}
}
13、可能 LoadLibrary 函数时可能会报错C++ "const char *" 类型的实参与 "LPCWSTR" 类型的形参不兼容,把字符集修改为 多字节字符集 即可,具体如下图

14、没有报错,调试运行,即可看到调用成功,具体如下图
