C++ 创建静态链接库和动态链接库

article/2025/9/29 8:54:47

上篇文章演示了如何使用C++ 编译的静态链接库和动态链接库,本篇文章主要介绍如何创建静态链接库和动态链接库,本文使用的工具是visual studio 2019 企业版,需要安装对应的C++sdk,可以参考网上其他文章,本问不在赘述。

一、创建静态链接库

使用VS 2019 创建C++ 静态链接库,新建项目,选择 C++ 静态库

删除多余的.h以及.cpp文件,添加TestAdd.h,以及TestAdd.cpp文件,如图所示

 TestAdd.h,以及TestAdd.cpp文件内容如下:

#pragma once
//extern "C" __declspec(dllexport) int __stdcall sumA(int a, int b);
//extern "C" __declspec(dllexport) int __stdcall minusA(int a, int b);__declspec(dllexport) int sumA(int a, int b);
__declspec(dllexport) int minusA(int a, int b);
//#define DLLEXPORT extern "C" __declspec(dllexport)
//
//DLLEXPORT int sumA(int a, int b)
//{
//    return a + b;
//}
//
//DLLEXPORT int minusA(int a, int b)
//{
//    return a - b;
//}__declspec(dllexport)int sumA(int a, int b)
{return a + b;
}int minusA(int a, int b)
{return a - b;
}//
//__declspec(dllexport) int sumA(int a, int b);
//__declspec(dllexport) int minusA(int a, int b);

上述TestAdd.h,以及TestAdd.cpp文件创建以后,选择项目,右键属性,配置属性 C/C++ 预编译头 中预编译头,选择 不使用预编译头,然后应用,确定。

 选择项目编译生成,即可上生成TestStaticLib.lib

 其他地方使用的时候需要复制TestStaticLib.lib和头文件TestAdd.h即可使用,使用方式有三种,哪一种都可以使用TestStaticLib.lib中的方法接口,如下:

首先在需要引用静态库的项目中引用头文件TestAdd.h,代码 :#include “TestAdd.h”,如项目A引用静态库,即在项目A的.cpp中添加#include “TestAdd.h”即可,下面以项目A来展示。

1、常规引用静态库

    选择项目A,右键属性 配置属性 链接器  输入  附加依赖项,选择.lib的 静态库的位置即可,.cpp的代码中直接使用TestStaticLib.lib中的方法接口即可

2、选择项目A中的资源文件,添加TestStaticLib.lib静态库,.cpp的代码中直接使用TestStaticLib.lib中的方法接口即可

3、.cpp的代码中首先添加如下代码,,之后下面直接使用TestStaticLib.lib中的方法接口即可

      //语句:#pragma comment(lib,"TestStaticLib.lib"),可以替代手动链接lib文件,显示加载链接库。
      #pragma comment(lib,"TestStaticLib.lib")

      

二、创建动态链接库

使用VS 2019 创建C++ 动态链接库,新建项目,选择 C++ 动态库

 添加Add.h,以及Add.cpp文件,如图所示

 Add.h,以及Add.cpp文件内容如下:

#pragma once
extern "C" __declspec(dllexport) int __stdcall sum(int a, int b);
extern "C" __declspec(dllexport) int __stdcall minus(int a, int b);
#define DLLEXPORT extern "C" __declspec(dllexport)DLLEXPORT int sum(int a, int b)
{return a + b;
}DLLEXPORT int minus(int a, int b)
{return a - b;
}

上述Add.h,以及Add.cpp文件创建以后,选择项目,右键属性,配置属性 C/C++ 预编译头 中预编译头,选择 不使用预编译头,然后应用,确定。

 

 选择项目编译生成,即可上生成TestDll.dll

 其他地方使用的时候需要复制TestDll.dll即可使用,本文以MFC窗体项目使用演示,窗体.cpp文件中添加如下代码:

#include <iostream>#include "windows.h"/*
Windows头文件中包含可以加载DLL的函数。---注意要先声明一下对应的指针函数接口
*/
typedef int(*ptrSub)(int, int);
//HMODULE hMod = LoadLibrary(L"TestDll.dll");
//配置属性 高级 高级属性 字符集 使用Unicode字符集 改成  使用多字节字符集 就可以省略 _T以及LoadLibrary(L"TestDll.dll");中的L了,
HMODULE hMod = LoadLibrary("TestDll.dll");
/*
在调用DLL函数之前,要定义函数指针,用来调用函数。
可以看出,函数指针的类型与DLL中的要一致。
*/
//HMODULE hMod = LoadLibrary(L"AdbHelper.dll");
/*调用LoadLibrary函数加载DLL文件。加载成功,hMod指针不为空。这里也可以是一个地址加文件名
*/

窗体.cpp文件中添加2个按钮事件,测试加和减如下代码:

/// <summary>
/// 调用TestDll.dll中的加法函数--sum
/// </summary>
void CMFCWinformAppTestDlg::OnBnClickedButton11()
{if (hMod != NULL){/*如果加载成功,则可通过GetProcAddress函数获取DLL中需要调用的函数的地址。获取成功,sum指针不为空。*/ptrSub sum = (ptrSub)GetProcAddress(hMod, "sum");if (sum != NULL){int a = sum(10, 6);CString temp_value = _T("处理数据:");   //temp_value用来处理float值temp_value.Format(_T("%d"), a);//固定格式//AfxMessageBox("10 - 6 =" + temp_value);CString tempvalue = _T("10 - 6 =" + temp_value);MessageBox(tempvalue, _T("标题"), MB_USERICON | MB_OK);//std::cout << "10 + 6 = " << a << std::endl;/*获取地址成功后,通过sum调用函数功能。*/}//FreeLibrary(hMod);/*在完成调用功能后,不在需要DLL支持,则可以通过FreeLibrary函数释放DLL。*/}
}/// <summary>
/// 调用TestDll.dll中的减法法函数--minus
/// </summary>
void CMFCWinformAppTestDlg::OnBnClickedButton12()
{if (hMod != NULL){/*如果加载成功,则可通过GetProcAddress函数获取DLL中需要调用的函数的地址。获取成功,sum指针不为空。*/ptrSub minus = (ptrSub)GetProcAddress(hMod, "minus");if (minus != NULL){int a = minus(10, 6);CString temp_value = _T("");   //temp_value用来处理float值temp_value.Format(_T("%d"), a);//固定格式//AfxMessageBox("10 - 6 =" + temp_value);CString tempvalue = _T("10 - 6 =" + temp_value);//配置属性 高级 高级属性 字符集 使用Unicode字符集 改成  使用多字节字符集 就可以省略 _T以及LoadLibrary(L"TestDll.dll");中的L了,//CString tempvalue1 = ("10 - 6 =" + temp_value);//tempvalue.GetBuffer();MessageBox(tempvalue, _T("标题"), MB_USERICON | MB_OK);//int result = MessageBox(TEXT("10 - 6 = a"), TEXT("新建任务"), MB_YESNO);//std::cout << "10 - 6 = " << a << std::endl;/*获取地址成功后,通过sum调用函数功能。*/}FreeLibrary(hMod);/*在完成调用功能后,不在需要DLL支持,则可以通过FreeLibrary函数释放DLL。*/}
}

注意事项:

//HMODULE hMod = LoadLibrary(L"TestDll.dll");
//配置属性 高级 高级属性 字符集 使用Unicode字符集 改成 使用多字节字符集 就可以省略 _T以及LoadLibrary(L"TestDll.dll");中的L了,
HMODULE hMod = LoadLibrary("TestDll.dll");

其他语言的引用,如C#代码如下:

namespace HidHelperTest
{class TestDllUtils{[DllImport("TestDll.dll", EntryPoint = "minus")]public extern static int sum(int a, int b);[DllImport("TestDll.dll", EntryPoint = "minus")]public extern static int minus(int a, int b);} 
}

使用

 private void btOneMeter_Click(object sender, EventArgs e){int a= TestDllUtils.sum(1, 2);}


http://chatgpt.dhexx.cn/article/yfT5iGS2.shtml

相关文章

动态链接库和静态链接库

转载自&#xff1a;https://www.cnblogs.com/king-lps/p/7757919.html &#xff08;有删减&#xff09; 1. 库的介绍 库是写好的现有的&#xff0c;成熟的&#xff0c;可以复用的代码。现实中每个程序都要依赖很多基础的底层库&#xff0c;不可能每个人的代码都从零开始&…

静态链接库与动态链接库----C/C++

平时我们写程序都必须include很多头文件&#xff0c;因为可以避免重复造轮子&#xff0c;软件大厦可不是单靠一个人就能完成的。但是你是否知道引用的那些头文件中的函数是怎么被执行的呢&#xff1f;这就要牵扯到链接库了&#xff01;&#xff01;&#xff01; 库有两种&#…

【四、静态库与动态库(共享库)】揭开链接库的神秘面纱:手把手教你制作静态链接库与动态链接库

前言 不管是在 Windows 下开发&#xff0c;还是在 Linux 下开发&#xff0c;我们都会经常性的使用一些库文件&#xff0c;这些库文件的特点就是&#xff0c;我们可以看到接口的原型并通过这些接口来调用这个函数的功能&#xff0c;但是我们无法查看这个功能的实现。这就是库文…

静态链接库(.lib)和动态链接库(.dll)的使用

静态链接库(.lib)和动态链接库(.dll)的使用 文章目录 静态链接库(.lib)和动态链接库(.dll)的使用一、静态链接库1. 静态链接库概述2. 创建静态链接库3. 调用静态链接库 二、动态链接库(dynamic linking library)1. 动态链接库概述2. 创建动态链接库并导出函数导出函数两种方式1…

静态链接库

库 库的存在&#xff0c;大大方便了我们进行编程。因为有了库&#xff0c;我们不必再从0开始&#xff0c;例如我们大多数人C语言写的第一个程序Hello World!都是用了库函数。以printf为例&#xff0c;我们只需要在程序源代码中包含<stdio.h>这个头文件之后&#xff0c;就…

史上最全Java类型转换

讲类型转换之前&#xff0c;让我来贴张表 基本数据类型的表示范围 类型 长度 表示范围默认值byte8b-128&#xff5e;1270short16b-32768&#xff5e;327670int32b-21147483648&#xff5e;21474836470long64b-9223372036 854 775 808&#xff5e;9223372036 8547758070Lfloat3…

Java:类型转换

public class Demo04 {public static void main(String[] args) {//低--------------------------> 高// byte,short,char->int->long->float->doubleint i 128;byte b (byte) i ;//内存溢出//强制转换 &#xff08;类型&#xff09;变量名 高--低//自动转换…

java强转规则_java类型转换及其规则介绍

一、自动类型转换 整型、实型(常量)、字符型数据可以混合运算。运算中&#xff0c;不同类型的数据先转化为同一类型&#xff0c;然后进行运算。 数据类型转换必须满足如下规则&#xff1a; 1、不能对boolean类型进行类型转换。 2、不能把对象类型转换成不相关类的对象。 3、在把…

Sql-Java类型转换

Mysql-Java字段类型转换 mysql类型名大小用途对应Java类char0-255 bytes定长字符串 &#xff08;姓名、性别、学号&#xff09;Stringvarchar0-65535 bytes变长字符串&#xff08;比上面更长一点的那种&#xff09;Stringtinytext0-255 bytes比较短的那种文本数据&#xff08;…

JAVA类型转换及变量详解

类型转换 由于java是强类型语言&#xff0c;所以要进行有些运算的时候&#xff0c;需要用到类型转换。 byte&#xff08;1个字节&#xff09;,short&#xff08;2个字节&#xff09;,char&#xff08;2个字节&#xff09;----->int&#xff08;4个字节&#xff09;---->…

Java类型转换(自动类型转换+强制类型转换)

一、 自动类型转换(隐式类型转换) 整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。自动转换从低级到高级。 自动转换有以下规律: 1、小的类型自动转化为大的类型 2、整数类型可以自动转化为浮点类型,可能会产生舍入误…

Java的类型转换

需要类型转换的原因:因为Java是强类型的语言&#xff0c;所以有时可能要进行跨类型的运算&#xff0c;这就需要先进行类型转换&#xff0c;再进行运算。 类型转换分为&#xff1a; 强制类型转换(由高-->低时使用)&#xff0c;自动类型转换/ 隐式类型转换(由低-->高时使用…

java中的类型转换

java的基本数据类型 1.数值型&#xff1a;byte&#xff0c;short&#xff0c;int&#xff0c;long&#xff0c;float&#xff0c;double 2.字符型&#xff1a;char 3.布尔型&#xff1a;boolean 数据类型占据字节数byte1个字节short2个字节int4个字节long8个字节float4个字节…

Java中各种类型的转化

目录 一.Integer和int之间的类型转化 1.自动装箱 2.构造器方法 3.Integer.valueOf(int i) 二.Integer和String之间的类型转换 1.String转换为Integer 1.Integer.parseInt(String s) ​编辑 2.Integer.valueOf(String s) 2.Integer转换为String 1.Integer.toString() …

【JAVA】Java中的类型转换

目录 1.自动类型转换&#xff08;隐式转换&#xff0c;小类型转换为大类型&#xff09; 2.强制类型转换&#xff08;显示转换&#xff0c;大类型转换为小类型&#xff09; 3.小于4字节的类型转换问题 3.1 byte<->int 3.2 char<->int 3.3 String<->int …

Java 类型转换

一、自动类型转换(隐式类型转换) 整型、实型(常量)、字符型数据可以混合运算。不同类型的数据先转化为同类型再进行运算 自动转换按从低级到高级顺序: char ↓ Byte→short→int→long---›float→double 自动转换有以下规律&#xff1a; 小的类型自动转化为大的类型 整数…

java类型转换

文章目录 1、什么是类型转换&#xff1f; 2、掌握常见数据类型的范围大小 3、自动类型转换 3.1 int转换为double 3.2 char转换为int类型 4、强制类型转换 4.1、强制类型转换格式 5、注意事项 1、什么是类型转换&#xff1f; 在java中类型转换是一个非常重要的知识点。因…

java中常见类型的转换以及方法总结

1.char、String、int类型之间的转换 1.1 char和String的区别 char是表示的是字符&#xff0c;定义的时候用单引号&#xff0c;只能存储一个字符。例如; char‘d’. String表示的是字符串&#xff0c;定义的时候用双引号&#xff0c;可以存储一个或者多个字符。例如&#xff1…

CentOs 无法启动网络,用ip addr看不到IP地址

1.无法启动网卡&#xff0c;启动报file exist 原因1&#xff1a;可能是别的网络与网络冲突 解决&#xff1a;关闭NetworkManager 原因2&#xff1a;etc/sysconfig/network-scripts下的ifcfg开头的文件有内容有冲突 解决&#xff1a;删除一些对应文件 如果还是不行&#xf…

ip命令的使用方式(临时设定:ip addr ,ifconfig)

对外开放&#xff0c;能和主机直接进行交流的设备叫做网卡 内部交流&#xff0c;系统内部服务与服务之间的接口&#xff0c;为回环接口 lo##回环设备 [rootlocalhost 桌面]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default…