C++ 创建静态链接库和动态链接库
上篇文章演示了如恶化使用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); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2019-07-18 WebSocket——SuperWebSocket实现服务端和客户端