首页 > 编程语言 >VS2019 使用 C/C++ 动态链接库 并 进行调用

VS2019 使用 C/C++ 动态链接库 并 进行调用

时间:2022-10-11 21:01:35浏览次数:95  
标签:std 文件 cout lib VS2019 int double C++ 动态链接库

 

vs2019生成dll并调用的实现示例:​​https://www.jb51.net/article/179759.htm​

 

1. VS 中生成动态链接库的三种方式(导出函数)

 

开发环境:VS2019

 

创建动态链接库项目

新建项目,搜索 DLL ,选择 “ 具有导出项的(DLL)动态链接库 ”,

VS2019 使用 C/C++ 动态链接库 并 进行调用_c++

输入项目名称,选择项目所在目录,然后点击 创建

VS2019 使用 C/C++ 动态链接库 并 进行调用_头文件_02

生成如下图所示的文件结构:

VS2019 使用 C/C++ 动态链接库 并 进行调用_c++_03

 

 

导出动态链接库

 

方法一 :声明导出

 

1、以 C++ 的方式声明导出。

在 CPP_DLL.cpp 文件中添加下面的函数,在函数声明前添加 _declspec(dllexport)

// C++ 的方式声明导出
_declspec(dllexport) int addFunc(int a, int b);
int addFunc(int a, int b)
{
return a + b;
}

示例截图:

VS2019 使用 C/C++ 动态链接库 并 进行调用_c++_04

 

2、以 C 的方式声明导出。

在 CPP_DLL.cpp 文件中添加下面的函数,在函数声明前添加 extern "C"  _declspec(dllexport)

// C 的方式声明导出
extern "C"
{
_declspec(dllexport) int subFunc(int a, int b);
int subFunc(int a, int b)
{
return a + b;
}

}

示例截图:

VS2019 使用 C/C++ 动态链接库 并 进行调用_c++_05

然后点击 “ 生成解决方案 ” ,就可以在工程目录的 debug 目录或者 release 目录下(这取决你生成的是debug版本还是release版本)生成了动态链接库的相关文件。第三方调用时关键的文件为 .lib文件.dll文件 以及工程目录下的 .h头文件

 

 

方法二: 模块定义文件导出

在项目中定义CPP_DLL.def 文件,该文件为模块导出文件

VS2019 使用 C/C++ 动态链接库 并 进行调用_头文件_06

在 CPP_DLL.cpp 文件中添加下面的函数

LIBRARY
EXPORTS
mulFunc
divFunc

示例截图:

VS2019 使用 C/C++ 动态链接库 并 进行调用_动态链接库_07

 

如果是 VS 平台,必须要在 连接器 中添加 .def 文件

VS2019 使用 C/C++ 动态链接库 并 进行调用_动态链接库_08

然后点击 “ 生成解决方案 ” ,就可以在工程目录的 debug 目录或者 release 目录下(这取决你生成的是debug版本还是release版本)生成了动态链接库的相关文件。第三方调用时关键的文件为 .lib文件.dll文件 以及工程目录下的 .h头文件

VS2019 使用 C/C++ 动态链接库 并 进行调用_动态链接库_09

对应 的 DLL 和 lib 文件

VS2019 使用 C/C++ 动态链接库 并 进行调用_动态链接库_10

 

 

 

2. 调用前面开发的动态链接库

 

1. 新建一个C/C++项目(test)

VS2019 使用 C/C++ 动态链接库 并 进行调用_动态链接库_11

VS2019 使用 C/C++ 动态链接库 并 进行调用_头文件_12

 

 

2. 将第三方库的 .h文件、.lib文件、.dll文件 复制进工程项目中

        .dll文件是程序运行需要载入的动态链接库,VS中调试时可以通过 项目->属性->调试->环境 栏目添加.dll文件的 path 而成功调试,但在独立运行.exe程序是须将.dll文件放到同一目录下。

        因此建议直接将 .dll文件.h头文件 和 .lib库文件,只要是能够通过路径找到即可,为了方便管理,建议建立文件夹,放置在项目目录下。

 

 

3. 在项目中调用第三方库

 

有三种方法可以调用第三方库。

 

(1)直接在代码前添加引用

因为直接引用 CPPDLL.h 头文件,所以需要把 动态链接库的 函数声明放在头文件中。

修改 CPP_DLL 的 .h 文件 和 cpp 文件,把 函数 声明放在 .h 中,函数定义放在 cpp 文件中。

CPP_DLL.h

// C++ 的方式声明导出
_declspec(dllexport) int addFunc(int a, int b);

// C 的方式声明导出
extern "C"
{
_declspec(dllexport) int subFunc(int a, int b);
}

int mulFunc(int a, int b);
double divFunc(double a, double b);

CPP_DLL.cpp

int addFunc(int a, int b)
{
return a + b;
}

int subFunc(int a, int b)
{
return a - b;
}


// def 文件形式
int mulFunc(int a, int b)
{
return a * b;
}

double divFunc(double a, double b)
{
return a / b;
}

重新生成 DLL 文件,并将 DLL  、lib 、.h 文件拷贝到对应目录

 

C++ 测试代码:

VS2019 使用 C/C++ 动态链接库 并 进行调用_c++_13

#include <iostream>
#include "./CPP_DLL.h" //通过相对路径或绝对路径添加头文件
#pragma comment (lib,"./CPPDLL.lib") // 添加 lib 文件


int main()
{
std::cout << "Hello World!\n";
std::cout << addFunc(1, 2) << std::endl;
std::cout << subFunc(3, 4) << std::endl;
std::cout << mulFunc(5, 6) << std::endl;
std::cout << divFunc(7, 8) << std::endl;
}

运行结果截图:

VS2019 使用 C/C++ 动态链接库 并 进行调用_动态链接库_14

 

 

(2)在解决方案管理面板中添加头文件和资源文件

添加一个现有项头文件,在文件夹中找到第三方库的头文件( CPP_DLL.h ),添加进新建立的项目。
添加一个现有项资源文件,在文件夹中找到第三方库的库文件( CPPDLL.lib ),添加进新建立的项目。

VS2019 使用 C/C++ 动态链接库 并 进行调用_头文件_15

 

 

(3)在 项目属性 -> 设置 中 添加 头文件 和 库文件

  • 项目->属性->VC++目录->包含目录 中添加第三方库的头文件
  • 库目录 下 添加 第三方库 的库文件(.lib文件)
  • 项目->属性->链接器->输入->附加依赖项中输入库文件名称

VS2019 使用 C/C++ 动态链接库 并 进行调用_头文件_16

VS2019 使用 C/C++ 动态链接库 并 进行调用_头文件_17

在函数中调用第三方库中的函数

#include <iostream>


int main()
{
std::cout << "Hello World!\n";
std::cout << addFunc(1, 2) << std::endl;
std::cout << subFunc(3, 4) << std::endl;
std::cout << mulFunc(5, 6) << std::endl;
std::cout << divFunc(7, 8) << std::endl;
}

 

 

4. 直接在代码里 load 动态库dll文件即可

这种方法不需要 include .h文件,不需要添加 lib库 和 lib库路径,

  • 引入 windows.h(必须)
  • 在 main 函数写下列语句调用 dll

        因为 C++ 声明 的 动态链接库会发生 Name Mangling,导致 编译后的函数名字会发生变化,所以需要使用 工具 查看 编译编译后的 动态链接库 对应的函数名。

        而 extern "C" 声明的 和 def 文件声明的,编译后的函数名不会发生变化,可以直接使用。

VS2019 自带的工具 dumpbin.exe 可以查看编译后的 动态链接库对应的 函数名。

VS2019 使用 C/C++ 动态链接库 并 进行调用_c++_18

打开命令行,输入命令 dumpbin -exports CPPDLL.dll

VS2019 使用 C/C++ 动态链接库 并 进行调用_动态链接库_19

结果截图:

VS2019 使用 C/C++ 动态链接库 并 进行调用_c++_20

所以 addFunc 不能直接使用,只能用被 name Mangling 后的名字 ,这里  addFunc 编译后的名字是 ?addFunc@@YAHHH@Z

示例程序代码:

#include <iostream>
#include <windows.h>


// 加、减、乘 都是 int 类型
typedef int(*lpFunc)(int a, int b); //后边为参数,前面为返回值

// 除法 是 double 类型
typedef double(*lpFuncD)(double a, double b); //后边为参数,前面为返回值


int main()
{
std::cout << "Hello World!\n";

HMODULE hModule;
hModule = LoadLibrary(L"CPPDLL.dll"); //调用DLL

lpFunc lpfunc = NULL;

// GetProcAddress为获取该函数的地址
// "?addFunc@@YAHHH@Z" 这个就是 C++ Name Mangling后的 addFunc 的函数名
lpfunc = (lpFunc)GetProcAddress(hModule, "?addFunc@@YAHHH@Z");
std::cout << lpfunc(1, 2) << std::endl;

/* 使用 C extern 和 def 文件定义的动态链接库,函数名不会发生变化 */
lpfunc = (lpFunc)GetProcAddress(hModule, "subFunc");
std::cout << lpfunc(3, 4) << std::endl;

lpfunc = (lpFunc)GetProcAddress(hModule, "mulFunc");
std::cout << lpfunc(5, 6) << std::endl;

lpFuncD lpfuncd = NULL;
lpfuncd = (lpFuncD)GetProcAddress(hModule, "divFunc");
std::cout << lpfuncd(7, 8) << std::endl;

//释放
FreeLibrary(hModule);
}

运行结果:

VS2019 使用 C/C++ 动态链接库 并 进行调用_动态链接库_21

 

 

方法 5:使用 lib 文件 和 dll 文件

  • CPPDLL.dll文件放到 debug 目录下,
  • 然后在项目中引入CPPDLL.lib文件。 链接器->输入->附加依赖项->编辑

VS2019 使用 C/C++ 动态链接库 并 进行调用_动态链接库_22

示例代码:

#include <iostream>


// addFunc 是使用 C++ 方式声明的,
_declspec(dllimport) int addFunc(int a, int b);

//subFunc 是 使用 extern "C" 声明的
extern "C" _declspec(dllimport) int subFunc(int a, int b);

// mulFunc 和 divFunc 是 使用 def 声明的
_declspec(dllimport) int mulFunc(int a, int b);
_declspec(dllimport) double divFunc(double a, double b);


int main()
{
std::cout << "Hello World!\n";

std::cout << addFunc(1, 2) << std::endl;
std::cout << subFunc(3, 4) << std::endl;
std::cout << mulFunc(5, 6) << std::endl;
std::cout << divFunc(7, 8) << std::endl;

return 0;
}

运行结果:

VS2019 使用 C/C++ 动态链接库 并 进行调用_头文件_23

还可以结合 第一种方法,使用  #pragma comment (lib,"./CPPDLL.lib")  //添加 lib 文件 

这样就不用 手动设置 添加 lib 文件了

#include <iostream>
#pragma comment (lib,"./CPPDLL.lib")


// addFunc 是使用 C++ 方式声明的,
_declspec(dllimport) int addFunc(int a, int b); // 声明 addFunc 函数

//subFunc 是 使用 extern "C" 声明的
extern "C" _declspec(dllimport) int subFunc(int a, int b); // 声明 subFunc 函数

// mulFunc 和 divFunc 是 使用 def 声明的
_declspec(dllimport) int mulFunc(int a, int b); // 声明 mulFunc 函数
_declspec(dllimport) double divFunc(double a, double b); // 声明 divFunc 函数


int main()
{
std::cout << "Hello World!\n";

std::cout << addFunc(1, 2) << std::endl;
std::cout << subFunc(3, 4) << std::endl;
std::cout << mulFunc(5, 6) << std::endl;
std::cout << divFunc(7, 8) << std::endl;

return 0;
}

 

 

 

 

 



标签:std,文件,cout,lib,VS2019,int,double,C++,动态链接库
From: https://blog.51cto.com/csnd/5747951

相关文章

  • [持续更新]C++从入门到精通
    C++编译器下载https://wwc.lanzoul.com/iRLXO0dnayde密码:33kg1.C++关键字关键词有哪些?在C++98/03关键词总计63个,分别是下面这些:asmdoifreturntypedefautodo......
  • C++ AFX_MANAGE_STATE(AfxGetStaticModuleState())的作用
    从AFX_MANAGE_STATE(AfxGetStaticModuleState())说起 AFX_MANAGE_STATE(AfxGetStaticModuleState())的作用:用于模块切换时的状态保护,1.AfxGetStaticModuleState()指向当前......
  • C++继承模型漫谈
    1、创建子类对象时,会优先创建父类部分,再创建子类部分,也就是子类对象是包含了两部分内容,(父类部分+子类部分)(图1)classTypeA{public:inta=10;voidv(){......
  • <三>从编译器角度理解C++代码的编译和链接原理
    代码点击查看代码**sum.cpp**intgdata=10;intsum(inta,intb){returna+b;}**main.cpp**externintgdata;intsum(int,int);intdata=20;intmain(......
  • VS2019 添加三方文件夹遇到的坑
    在开发新项目时需要用到一些三方API,这些三方API没有生成lib,所以我们在VS编译器中添加这些三方文件夹的头文件路径后会出现ERRORLNK2019的错误提示,这些提示通常都......
  • C++中class关键字
    在C++语言中​​class​​​是定义类的关键字,C++中也可以使用struct定义类。两者区别是,用​​class​​​定义的类,如果​​数据成员​​​或成员函数没有说明则默认为priva......
  • windows C++ 异常调用栈简析
    楔子以win11+vs2022运行VC++编译观察的结果。如果安装了VisualStudio2022,比如安装在D盘,则路径:D:\VisualStudio\IDE\VC\Tools\MSVC\14.33.31629下面包含了vcrun......
  • C++STL
    STL1.说说STL的基本组成部分STL由6部分组成:容器(Container)、算法(Algorithm)、迭代器(Iterator)、仿函数(Functionobject)、适配器(Adaptor)、空间配制器(Allocator)。容器......
  • Linux下的lua和boost c++的搭建和安装
    先下载lua,boostc++​​http://www.lua.org/versions.html#5.2​​​​http://www.boost.org/​​ ​​http://sourceforge.net/projects/luabind/​​1.安装lua[root@l......
  • 开源状态机代码生成 StateSmith 支持C/C++
     StateSmithStateSmithisacrossplatform,free/opensourcetoolforgeneratingstatemachines.Thegeneratedcodeishumanreadable,haszerodependencies......