Visual Studio 编写、调用(显式隐式)C++静态库

一.Visual Studio 编写C++动态链接库(2017版本);

  • 创建动态链接库项目        

        单击左上角“文件”菜单,选择“新建”->“项目”->“动态链接库(DLL);
        配置项目名称及解决方案名称后,点击“确定”。

        成功创建项目。

  • 生成动态链接库

        添加头文件“rovdll.h”和源文件“rovdll.cpp”。

 

        头文件中声明一个导出函数。

#pragma once

#include <cstdio>
#include <cstdint>

#ifdef BUILD_MYDLL //判断宏有没有定义,定义了则执行后面的语句,没有定义则报错
#define API_SYMBOL __declspec(dllexport)  //声明导出函数,类,对象供外面调用,
#else
#define API_SYMBOL __declspec(dllimport)  //从别的动态库中导入函数,类,对象
#endif

#define PidParamFileName "pidParam.json"

//导出函数,由于是c的接口所以得加extern "C" 
extern "C" API_SYMBOL int convert_arry(int* data, int len);

        按住“Alt”+“Enter”,单击函数名“convert_arry”,创建函数定义如下:

//为使dllexport有效,需在头文件前定义该宏
#define BUILD_MYDLL

#include "pch.h"
#include "rovdll.h"
#include <fstream>
#include <iostream>


using namespace std;

int convert_arry(int * data, int len)
{
	for (int i = 0; i < len; i++)
	{
		cout << data[i] << ",";
	}

	cout << endl;

	int nTotal = 0;
	for (int i = 0; i < len; i++)
	{
		nTotal += data[i];
		--data[i];
	}

	return nTotal;
}

        编译项目,右键“项目”点击“生成” 。

        生成成功。 

        项目目录下生成对应文件。 

二.创建应用程序隐式调用动态库;

        右键单击“解决方案”->“添加”->“新建项目”->“控制台应用”

 

        隐式调用需要三个文件:“.lib”、“.dll”、“.h”文件。

        1.先加入头文件,会发现include下面出现红色波浪号,提示“无法打开 源文件”。

        此时,需要为它提供一个搜索路径。
        右键点击“项目DemoInvokeDll”->"属性"。

        在“C/C++”、“常规”中附加“附加包含目录”。

        添加DemoDll的文件路径。

 

         点击“应用”、“确定”后,波浪线消失。

        2. 引入lib符号文件

        右键点击“项目DemoInvokeDll”->“属性”->“链接器”->“输入”;
        添加“附加依赖项”->“编辑”;
        输入“DemoDll.lib”->“确定”“应用”“”。

再给lib添加一个搜索路径:“链接器”->“常规” ->“附加库目录”->“编辑”

        加入链接库所在的目录,“确定”->“应用”->“确定”。

        3.在“DemoInvokeDll”中,编写调用代码。

#include <iostream>
#include "rovdll.h"
int main()
{
	int arr[] = { 3,6,7,8 };
	int nLen = sizeof(arr) / sizeof(int);
	int nTotal = convert_arry(arr, nLen);
	std::cout << "数组元素求和结果:" << nTotal << std::endl;
	std::cout << "数组元素新值:" << std::endl;
	for (int i = 0; i < nLen; i++) {
		std::cout << arr[i] << ",";
	}
}

        4.运行程序

        将“DemoInvokeDll”设为启动项目。

         运行项目,得到调试结果。结果正确,按空格退出。

三.创建应用程序显式调用动态库;

        显式调用只需要一个文件:“.dll”的动态库文件。

        右键单击“解决方案”->“添加”->“新建项目”->“控制台应用”

 

        在生成的“xsInvokeDll.cpp”中,按下列五步:

        第一步,创建一个别名,它引用的函数类型需要和dll中导出函数一致;

        第二步,加载DemoDll.dll 动态库文件;

        第三步,获取dll中的函数地址;

        第四步,调用函数;

        第五步,释放函数句柄。

代码如下:

#include <iostream>
#include <Windows.h>

//第一步,创建一个别名,它引用的函数类型需要和dll中导出函数一致。
typedef int(*LPDO_ARRAY)(int* pArr, int nlen);

int main()
{
	HINSTANCE hDll;        //定义一个实例句柄,引用动态库,需引入windows头文件
	LPDO_ARRAY IpDo_array; //定义一个函数指针,用来指向导出函数
	//第二步,加载DemoDll.dll 动态库文件
	hDll = LoadLibrary(L"DemoDll.dll");
	if (hDll != NULL) {
		//第三步,获取dll中的函数地址
		IpDo_array = (LPDO_ARRAY)GetProcAddress(hDll, "convert_arry");
		if (IpDo_array != NULL) {
		//第四步,调用函数
			int nArr[] = { 1,2,3,5 };
			int nlen = sizeof(nArr) / sizeof(int);
			int nRet;

			//通过函数指针IpDo_array调用函数
			nRet = IpDo_array(nArr, nlen);
			std::cout << "返回值:" << nRet << std::endl;
			std::cout << "数组新值:" ;
			for (int i = 0; i < nlen; ++i) {
				std::cout << nArr[i] << ",";
			}
		}
		//第五步,释放动态库句柄
		FreeLibrary(hDll);
	}
}

        调用方法1:将“DemoInvokeDll”设为启动项目,运行程序,得到结果。

        调用方法2:

        将“xsInvokeDll.exe”“DemoDll.dll”文件复制到D盘。

        用命令行方式执行 “xsInvokeDll.exe”,得到结果。

四.动态库和静态库的区别。

        静态库:当“应用程序代码”在编译的时候,把“静态库代码”一起打包为一个“可执行程序”。对于不同的可执行程序,无论是储存到硬盘,还是运行时加载到内存,它们都拥有各自静态库代码的拷贝。

        动态库:在编译的时候只有少量的符号信息,会打包到可执行程序里,主要的程序代码会被独立编译成一个dll文件,同时,多个应用程序可以共享这个dll文件。并且,动态库可以实现运行时的动态加载,还可以被第三方程序调用。

参考:

Visual Studio 2019-编写C++动态链接库(老蓝的程序实践)

VS2019环境下C++动态链接库(DLL)的创建与调用(很详细)

C# 调用C++封装的dll库函数的方法(一)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值