当前位置: 首页 > news >正文

【cmake实战六】如何使用编译的库(动态库dll)——windows系统

【cmake实战六】如何使用编译的库(动态库dll)——windows系统

  • 一、文件目录
    • 1、main.cpp
    • 2、CmakeLists.txt
    • 3、haha
  • 二、构建、编译、运行
    • 1、构建(新建build目录,在build目录下执行)
    • 2、编译
    • 3、运行
  • 三、知识讲解
    • 1、LoadLibrary
    • 2、FreeLibrary
    • 3、GetProcAddress
    • 4、__declspec
    • 5、extern "C"

一、文件目录

在这里插入图片描述

1、main.cpp

#include<iostream>
#include<windows.h>
using namespace std;
void loadDll(string dllname, HMODULE& handle)
{
	//handle = (handle_t)::LoadLibrary(dllname.c_str());
	handle = (HMODULE)::LoadLibrary(dllname.c_str());
}

bool freeDll(HMODULE& handle)
{
	bool re = FreeLibrary(handle);
	return re;
}
int main()
{
	cout<<"hello world"<<endl;
	//handle_t handle = nullptr;
	HMODULE handle = nullptr;
	loadDll("C:\\Users\\jx\\Desktop\\test06\\lib\\Debug\\haha.dll", handle);
	if (nullptr == handle)
	{
		cout << "fail to load dll" << endl;
	}
	
	cout << "sucess to load dll" << endl;

	typedef void (*print)();

	print hahafunc=(print)GetProcAddress(handle, "haha");
	hahafunc();

	bool re = freeDll(handle);
	if (re)
	{
		cout << "success to unload dll" << endl;
	}

	return 0;
}

2、CmakeLists.txt

CMAKE_MINIMUM_REQUIRED(VERSION 3.8.0)

PROJECT(NEWHELLO)

ADD_EXECUTABLE(hello main.cpp)

ADD_SUBDIRECTORY(haha)

SET(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/lib")
SET(LIBRARY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/lib")

3、haha

  • haha.h
#ifndef HAHA_H
#define HAHA_H

#include<iostream>

extern "C" __declspec(dllexport) void haha();
#endif

  • haha.cpp
#include "haha.h"
using namespace std;
void haha()
{
	cout<<"haha"<<endl;
}
  • CmakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 3.8.0)

SET(TARGET "haha")

#ADD_LIBRARY(haha STATIC haha.cpp)
ADD_LIBRARY(haha SHARED haha.cpp)

SET(EXECUTABLE_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/lib")
SET(LIBRARY_OUTPUT_PATH "${PROJECT_SOURCE_DIR}/lib")

二、构建、编译、运行

1、构建(新建build目录,在build目录下执行)

cmake ..

2、编译

devenv.com NEWHELLO.sln /Build "Debug|x64"

3、运行

.\hello.exe

在这里插入图片描述

三、知识讲解

1、LoadLibrary

  • 进程调用 LoadLibrary 以显式链接到 DLL。 如果函数执行成功,它会将指定的 DLL 映射到调用进程的地址空间中并返回该 DLL 的句柄。 此句柄可以与其他函数(如 GetProcAddress 和 FreeLibrary)一起在显式链接中使用。
  • https://docs.microsoft.com/zh-cn/cpp/build/loadlibrary-and-afxloadlibrary?view=msvc-170
  • LoadLibrary微软提供,linux下不可用,同linux下的dlopen

2、FreeLibrary

  • 当不再需要 DLL 模块时,显式链接到 DLL 的进程会调用 FreeLibrary 函数。 此函数使模块的引用计数递减。 而且,如果引用计数为零,则从进程的地址空间取消映射。
  • FreeLibrary微软提供,linux下不可用,同linux下的dlclose

参考- https://docs.microsoft.com/zh-cn/cpp/build/freelibrary-and-afxfreelibrary?view=msvc-170

3、GetProcAddress

  • 显式链接到 DLL 的进程会调用 GetProcAddress,以获取 DLL 中导出函数的地址。 可使用返回的函数指针调用 DLL 函数。 GetProcAddress 采用 DLL 模块句柄(由 LoadLibrary返回)作为参数,并采用要调用的函数的名称或函数的导出序号。
  • 微软提供,linux下无法使用,同linux下的dlsym

参考:https://docs.microsoft.com/zh-cn/cpp/build/getprocaddress?view=msvc-170
https://www.cnblogs.com/avexer/p/3258291.html

4、__declspec

  • dllexportdllimport存储类属性是特定于 C 和 C++ 语言的扩展。 可以使用它们从 DLL 中导出或向其中导入函数、数据和对象。
  • 微软提供的,linux下无法使用,同linux下的__attribute__ ((visibility(“default”)))

参考:https://docs.microsoft.com/zh-cn/cpp/cpp/dllexport-dllimport?view=msvc-170
https://blog.csdn.net/yu704645129/article/details/53171315

5、extern “C”

1.使用LoadLibrary函数来加载dll库
2.C/C++中extern关键字详解

相关文章:

  • 【vue3源码】九、ref源码解析
  • Input系统学习-----injectInputEvent注入事件调用流程
  • Java项目:SSM物业缴费管理系统
  • 函数指针(函数作为参数传递给其他函数)
  • 2023考研推荐新闻传播专业入门可以看的好书
  • 解决Long类型web前端精度丢失问题
  • Docker服务编排
  • 为什么自动化营销对于独立站运营来说很重要?
  • 服务器模型选择
  • 使用Android studio开发一个数独游戏APP 系列第二讲
  • MySQL中的时间类型
  • linux的基础指令
  • Docker容器中安装Mysql和Redis等全过程(以在阿里云服务器中的Docker安装Mysql和Redis为例)
  • java---SPFA算法---判断负权回路(每日一道算法2022.8.31)
  • 操作系统(Linux)
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 3.7、@ResponseBody 和 @RestController
  • Angular4 模板式表单用法以及验证
  • bootstrap创建登录注册页面
  • es6(二):字符串的扩展
  • JavaScript中的对象个人分享
  • Laravel Telescope:优雅的应用调试工具
  • Making An Indicator With Pure CSS
  • nfs客户端进程变D,延伸linux的lock
  • tensorflow学习笔记3——MNIST应用篇
  • Windows Containers 大冒险: 容器网络
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 前端
  • 如何利用MongoDB打造TOP榜小程序
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • 哈罗单车融资几十亿元,蚂蚁金服与春华资本加持 ...
  • ​Kaggle X光肺炎检测比赛第二名方案解析 | CVPR 2020 Workshop
  • ​用户画像从0到100的构建思路
  • #etcd#安装时出错
  • (2)(2.10) LTM telemetry
  • (TOJ2804)Even? Odd?
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (使用vite搭建vue3项目(vite + vue3 + vue router + pinia + element plus))
  • (四)库存超卖案例实战——优化redis分布式锁
  • (四)七种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (图)IntelliTrace Tools 跟踪云端程序
  • (一)Linux+Windows下安装ffmpeg
  • (转载)在C#用WM_COPYDATA消息来实现两个进程之间传递数据
  • 、写入Shellcode到注册表上线
  • ... fatal error LINK1120:1个无法解析的外部命令 的解决办法
  • .form文件_一篇文章学会文件上传
  • .java 9 找不到符号_java找不到符号
  • .NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。
  • .net 桌面开发 运行一阵子就自动关闭_聊城旋转门家用价格大约是多少,全自动旋转门,期待合作...
  • .NET导入Excel数据
  • .net和jar包windows服务部署
  • .net连接MySQL的方法
  • /bin/rm: 参数列表过长"的解决办法
  • /var/spool/postfix/maildrop 下有大量文件