Win32动态库介绍及全局函数导出

news2024/11/18 12:21:44

Windows操作系统中,库分为动态链接库(dll)和静态链接库(lib)

动态库是Windows中实现代码共享的一种方式。它是一个二进制式文件,不可单独运行,需要调用方调用才能运行。在Windows中,动态库可以被多种编程语言所支持。

静态链接库不同于动态链接库(dll),在静态库情况下,函数和数据被编译进一个二进制 文件(通常扩展名为*.lib),Visual C++的编译器在链接过程中将从静态库中恢复这些函数和数据并把他们和应用程序中的其他模块组合在一起生成可执行文件。这个过程称为"静态链接",此时因为应用程序所需的全部内容都是从库中复制了出来,所以静态库本身并不需要与可执行文件一起发行。

使用动态库有以下好处:

1、有利于代码和数据的共享

2、有利于模块化开发

3、有利于软件升级

4、代码保护

动态链接库又分为Win32动态链接库和MFC动态链接库。区别就是是否使用了MFC类

Win32 DLL编程

 如何导出Win32 DLL

1、通过关键字_declspec(dllexport导出)

新建一个C++ dll工程 DllExportTest

新建一个DllExportTest..h文件

输入

1 #pragma once
2 
3 __declspec(dllexport) void PrintHelloWorld();

在DllExportTest.cpp中输入

 1 #include "stdafx.h"
 2 #include"DllExportTest.h"
 3 #include<iostream>
 4 
 5 using namespace std;
 6 
 7 void PrintHelloWorld()
 8 {
 9     cout << "HelloWorld" << endl;
10 }

2、通过模块定义文件导出

新建一个C++ dll工程 DllExportWithDEFTest

新建一个DllExportWithDEFTest.h,输入

1 #pragma once
2 
3 void PrintHelloWorld();

在DllExportWithDEFTest.cpp中输入

 1 #include "stdafx.h"
 2 #include"DllExportWithDEFTest.h"
 3 #include<iostream>
 4 
 5 using namespace std;
 6 
 7 void PrintHelloWorld()
 8 {
 9     cout << "HelloWorld" << endl;
10 }

然后在“源文件”上右键选择“添加新项”,选择“代码”->”模块定义文件(.def)“

.def常用格式如下

LIBRARY   DllName                  //dll名字, DllName可以为空
DESCRIPTION    DllDescription      //dll 描述 这一行可以省略
EXPORTS FuncOrVariables             //要导出的函数名或变量的名字

我在前面的代码中定义了PrintHelloWorld函数,要将它导出,可以这样定义.def文件

LIBRARY   
EXPORTS
PrintHelloWorld

如果要将PrintHelloWorld函数导出为其它的名字,如MyFuncName,可以这样定义.def文件

LIBRARY   
EXPORTS
MyFuncName = PrintHelloWorld

如何使用导出的函数

C#调用可以参考以下链接

C#与C++互操作 - zhaotianff - 博客园

C++调用

分为隐式链接和显式链接两种方式

隐式链接

步骤如下

1、引入lib文件

2、引入头文件

3、调用dll中的数据

新建一个C++ 控制台程序 InvokeDll

 

打开项目的目录,建立lib和include文件夹(这个操作不是必须的,.h和.lib可以通过路径引用,不一定非要建立这样的文件夹,但这样操作会更好管理)

把前面生成的DllExportTest.lib拷到lib文件夹下,把DllExportTest.h拷到include文件夹下

然后在项目上单击右键,选择属性,依次选择配置属性-》链接器-》常规-》附加库目录。新建一个路径,选择刚才建立 的lib文件夹,单击确定

再选择输入-》附加依赖项,增加DllExportTest.lib

在InvokeDll.cpp中输入以下代码

1 #include "stdafx.h"
2 #include "include\DllExportTest.h"
3 
4 
5 int main()
6 {
7     PrintHelloWorld();
8     return 0;
9 }

运行之后可以看到屏幕输出HelloWorld

隐式链接还有一种方式,使用指令#pragma comment来引用lib文件

新建一个C++控制台程序 InvokeDll_2

复制InvokeDll项目路径下的include和lib文件夹到InvokeDll_2的项目路径下,在InvokeDll_2.cpp中输入以下代码

 1 #include "stdafx.h"
 2 #include "./include/DllExportTest.h"
 3 
 4 #pragma comment(lib,"./lib/DllExportTest.lib")
 5 
 6 int main()
 7 {
 8     PrintHelloWorld();
 9     return 0;
10 }

运行之后也可以看到屏幕输出HelloWorld

 显式链接

显示链接主要是通过调用LoadLibrary、GetProcAddress、FreeLibrary这三个API函数来实现

LoadLibrary()

声明如下

HMODULE WINAPI LoadLibrary( _In_ LPCTSTR lpFileName);

用于载入指定的动态链接库

GetProcAddress()

声明如下

FARPROC GetProcAddress( HMODULE hModule, LPCSTR lpProcName );

用于检索指定的动态链接库中函数地址

FreeLibrary()

声明如下

BOOL FreeLibrary( HMODULE hLibModule );

用于释放指定的动态链接库

新建一个C++控制台程序 InvokeDllExplicitly,在InvokeDllExplicitly.cpp中输入以下代码

 1 #include "stdafx.h"
 2 #include <Windows.h>
 3 
 4 typedef void(*MyFunc)();  //后面是函数签名部分,需要跟导出函数中的保持一致。这个函数没有参数,所以后面部分为空
 5 
 6 int main()
 7 {
 8     HMODULE hDll = NULL;
 9     MyFunc myFunc = NULL;
10 
11     //加载库
12     hDll= LoadLibrary("./DllExportTest.dll");
13 
14     if (hDll)
15     {
16         //获取函数或变量的地址
17         myFunc =(MyFunc)GetProcAddress(hDll, "PrintHelloWorld");
18 
19         if (myFunc)
20         {
21             //调用函数
22             myFunc();
23         }
24     }
25 
26     //释放动态链接库
27     FreeLibrary(hDll);
28 
29     return 0;
30 }

运行可以看到屏幕输出 HelloWorld

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2166726.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【测试】开发模型

什么是模型 规范的流程是在时代的演变下逐渐成型&#xff0c;并不是一开始就是规范的流程。 你以为的模型 实际的模型 随着软件⼯程学科的发展&#xff0c;⼈们对计算机软件的认识逐渐深⼊。软件⼯作的范围不仅仅局限在程序编写&#xff0c;⽽是扩展到了整个软件⽣命周期&…

5分钟快速制作高质量、美观的Excel甘特图

你是否还在为如何制作甘特图而感到苦恼&#xff1f; 是否因为甘特图制作过程繁琐、耗时过长而影响了你的工作效率&#xff1f; 是否每当任务计划发生变更时&#xff0c;都需要反复重新绘制甘特图&#xff0c;让你感到疲惫不堪&#xff1f; 又或者&#xff0c;你是否一直渴望…

戴尔笔记本怎么重装系统_戴尔笔记本重装系统win10教程(支持新旧机型安装)

戴尔笔记本怎么重装系统&#xff1f;戴尔笔记本这几年默认预装win10家庭版和win11家庭版。有的用户用上了预装win11家庭版的戴尔笔记本&#xff0c;使用一段时间依然不习惯&#xff0c;于是想退回win10。但不知道怎么重装win10&#xff0c;这几年的戴尔笔记本建议采用U盘方式安…

【GUI设计】基于Matlab的图像处理GUI系统(2),matlab实现

博主简介&#xff1a;matlab图像代码项目合作&#xff08;扣扣&#xff1a;3249726188&#xff09; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 本次案例是基于Matlab的图像处理GUI系统&#xff08;2&#xff09;&#xff0c;用matlab实现。…

工装检测摄像机

工装检测摄像机是一种结合了监控摄像技术和智能分析技术的先进设备&#xff0c;旨在通过实时监测和分析员工穿着的工作服装是否符合规定标准&#xff0c;识别是否存在违规穿着情况&#xff0c;并及时发出警报提醒相关人员。这种摄像机在生产制造、工业安全、医疗卫生等领域有着…

[240926] Pixtral 12B: 开源多模态模型,兼顾推理与文本能力 | OpenAPI 入门指南

目录 Pixtral 12B: 开源多模态模型&#xff0c;兼顾推理与文本能力性能评估方案指令遵循 架构 OpenAPI 入门指南一、什么是 OpenAPI&#xff1f;二、OpenAPI 的概念三、OpenAPI 的结构四、OpenAPI 的格式五、OpenAPI 的优势 Pixtral 12B: 开源多模态模型&#xff0c;兼顾推理与…

环形链表-注意起始双指针的位置

题目描述&#xff1a; 个人题解&#xff1a; 快慢指针法&#xff0c;注意起始双指针的位置&#xff0c;一个在head位置&#xff0c;一个在head->next的位置&#xff0c;慢指针每次只移动一步&#xff0c;而快指针每次移动两步。初始时&#xff0c;慢指针在位置 head&#xf…

微信小程序-使用vant组件库

文章目录 微信小程序-使用vant组件库概述构建npm构建步骤使用vant注册使用添加事件使用插槽 样式覆盖解除样式隔离使用外部样式类使用CSS变量 微信小程序-使用vant组件库 概述 Vant Weapp 是有赞前端团队开源的小程序 UI 组件库&#xff0c;基于微信小程序的自定义组件开发&a…

ESP8266 make flash ESPBAUD=921600加快eclipse烧录速度

要点&#xff1a; 1&#xff09;Default baud rate (115200 baud) 既是烧录速度 2&#xff09;UART0、UART1的波特率都同make monitor的74880 3&#xff09;make flash时设置波特率&#xff0c;即实际使用的波特率 1. 波特率&#xff0c;默认115200&#xff0c;需27.8s Writi…

前端框架对比、分析与选择

在现代Web开发中&#xff0c;选择合适的前端框架对于项目的成功至关重要。本文将详细对比分析Vue.js、Angular、React和Layui这四种前端框架&#xff0c;帮助开发者做出明智的选择。 一、概述 1. Vue.js Vue.js是由尤雨溪创建的一个渐进式JavaScript框架&#xff0c;旨在通过简…

在精益生产现场管理和改善中,如何制定合理的奖励制度?

在精益生产的广阔实践领域中&#xff0c;现场管理与改善是推动企业持续进步、提升竞争力的关键环节。而制定合理的奖励制度&#xff0c;则是激发员工积极性、促进团队协作、加速改善进程的重要驱动力。本文&#xff0c;深圳天行健企业管理咨询公司将深入探讨在精益生产现场管理…

XSS | XSS 漏洞介绍

关注这个漏洞的其他相关笔记&#xff1a;XSS 漏洞 - 学习手册-CSDN博客 0x01&#xff1a;XSS 漏洞简介 跨站脚本&#xff08;Cross-Site Scripting&#xff0c;简称为 XSS&#xff09;攻击&#xff0c;是一种针对网站应用程序的安全漏洞进行攻击的技术&#xff0c;是代码注入的…

【在Linux世界中追寻伟大的One Piece】IP分片和组装的具体过程

目录 1 -> IP分片和组装的具体过程 2 -> 分片与组装的过程 2.1 -> 分片 2.2 -> 组装 3 -> 分片与组装的示意图 3.1 -> 分片组装场景 1 -> IP分片和组装的具体过程 16位标识(id)&#xff1a;唯一的标识主机发送的报文。如果IP报文在数据链路层被分片…

linux入门到实操-11 Linux用户权限管理:添加和查看用户、获取root权限和删除用户、用户组管理

教程来源&#xff1a;B站视频BV1WY4y1H7d3 3天搞定Linux&#xff0c;1天搞定Shell&#xff0c;清华学神带你通关_哔哩哔哩_bilibili 整理汇总的课程内容笔记和课程资料&#xff08;包含课程同版本linux系统文件等内容&#xff09;&#xff0c;供大家学习交流下载&#xff1a;…

Verba - Weaviate RAG 私人助理

文章目录 一、关于 Verba什么是Verba&#xff1f;功能列表 二、Verba入门安装部署 三、API密钥1、Weaviate2、Ollama3、UNSTRUCTURED4、AssemblyAI5、OpenAI6、HuggingFace 四、如何使用pip进行部署五、如何从源代码构建六、如何使用Docker安装VerbaVerba Walkthrough选择您的部…

进来看看吧,产品经理做APP从头到尾的所有工作流程详解!

一、项目启动前 从事产品的工作一年多&#xff0c;但自己一直苦于这样或者那样的困惑&#xff0c;很多人想要从事产品&#xff0c;或者老板自己创业要亲自承担产品一职&#xff0c;但他们对产品这个岗位的认识却不明晰&#xff0c;有的以为是纯粹的画原型&#xff0c;有的是以…

BACnet MS/TP协议解析(3)

1、MS/TP帧格式 例如数据&#xff08;hex&#xff09;&#xff1a;55 FF 01 03 02 00 00 D7 0x550xff0x010x030x020x000x000xD7BACnet数据BACnet数据CRC帧头帧类型目的地址源地址BACnet数据长度&#xff0c;大端CRC 2、帧类型 帧类型目前定义为 0-7&#xff0c;8-127 为 AS…

vue3 vite模式配置测试,开发、生产环境以及代理配置

1、首先在根目录下创建三个文本文件&#xff1a;.env.development&#xff0c;.env.production&#xff0c;.env.test .env.development中的内容为&#xff1a; // 开发环境 .env.development NODE_ENV development VITE_APP_MODE development VITE_OUTPUTDIR dist_dev /…

基于Java的宠物之家小程序 宠物服务小程序【源码+调试】

精彩专栏推荐订阅&#xff1a;在下方主页&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主页&#xff1a;计算机毕设木哥&#x1f525; &#x1f496; 文章目录 一、宠物之家小程…

FPGA第 11 篇,Verilog 系统函数( Verilog 中的系统函数)

前言 Verilog 作为一种强大的硬件描述语言&#xff0c;不仅提供了用于设计和仿真数字电路的基础语法&#xff0c;还包含了丰富的系统函数&#xff0c;帮助我们高效地完成复杂的硬件操作。系统函数是 Verilog 语言中预定义的特殊函数&#xff0c;通常以 $ 开头&#xff0c;它们…