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文件

输入

 #pragma once

 __declspec(dllexport) void PrintHelloWorld();

在DllExportTest.cpp中输入

 #include "stdafx.h"
#include"DllExportTest.h"
#include<iostream> using namespace std; void PrintHelloWorld()
{
cout << "HelloWorld" << endl;
}

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

新建一个C++ dll工程 DllExportWithDEFTest

新建一个DllExportWithDEFTest.h,输入

 #pragma once

 void PrintHelloWorld();

在DllExportWithDEFTest.cpp中输入

 #include "stdafx.h"
#include"DllExportWithDEFTest.h"
#include<iostream> using namespace std; void PrintHelloWorld()
{
cout << "HelloWorld" << endl;
}

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

.def常用格式如下

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

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

LIBRARY
EXPORTS
PrintHelloWorld

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

LIBRARY
EXPORTS
MyFuncName = PrintHelloWorld

如何使用导出的函数

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

https://www.cnblogs.com/zhaotianff/p/8991847.html

C++调用

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

隐式链接

步骤如下

1、引入lib文件

2、引入头文件

3、调用dll中的数据

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

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

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

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

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

在InvokeDll.cpp中输入以下代码

 #include "stdafx.h"
#include "include\DllExportTest.h" int main()
{
PrintHelloWorld();
return ;
}

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

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

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

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

 #include "stdafx.h"
#include "./include/DllExportTest.h" #pragma comment(lib,"./lib/DllExportTest.lib") int main()
{
PrintHelloWorld();
return ;
}

运行之后也可以看到屏幕输出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中输入以下代码

 #include "stdafx.h"
#include <Windows.h> typedef void(*MyFunc)(); //后面是函数签名部分,需要跟导出函数中的保持一致。这个函数没有参数,所以后面部分为空 int main()
{
HMODULE hDll = NULL;
MyFunc myFunc = NULL; //加载库
hDll= LoadLibrary("./DllExportTest.dll"); if (hDll)
{
//获取函数或变量的地址
myFunc =(MyFunc)GetProcAddress(hDll, "PrintHelloWorld"); if (myFunc)
{
//调用函数
myFunc();
}
} //释放动态链接库
FreeLibrary(hDll); return ;
}

运行可以看到屏幕输出 HelloWorld

Windows中的库编程的更多相关文章

  1. windows中静态库lib和动态dll的区别及使用方法

    1. 静态库lib和动态dll的区别 1.1 项目类型 VS在建Win32项目时,有以下选项: windows应用程序控制台应用程序DLL静态库最后两个类型:DLL和静态库,这两种项目类型是不可以单独 ...

  2. 在windows下的QT编程中的_TCHAR与QString之间的转换

    由于在windows下的QT编程中,如果涉及到使用微软的API,那么不可避免使用_TCHAR这些类型,因此在网上查了一下,其中一个老外的论坛有人给出了这个转换,因此在这里做一下笔记 : )#ifdef ...

  3. Python中使用模块和库编程

    """ python中使用模块和库编程 导入模块 import modulename [as alias] from modulename import fun1,fun ...

  4. winsock教程- windows下的socket编程(c语言实现)

    winsock教程- windows下的socket编程(c语言实现) 使用winsock进行socket 编程     这是一个学习windows下socket编程(c语言)的快速指南.这是因为一下 ...

  5. Linux与Windows中动态链接库的分析与对比

    摘要:动态链接库技术实现和设计程序常用的技术,在Windows和Linux系统中都有动态库的概念,采用动态库可以有效的减少程序大小,节省空间,提高效率,增加程序的可扩展性,便于模块化管理.但不同操作系 ...

  6. PHP中GD库是做什么用的? PHP GD库介绍11111111

    什么是gd库?    gd库是php处理图形的扩展库,gd库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片. 在网站上GD库通常用来生成缩略图或者用来对图片加水印或者对网站数据 ...

  7. STM32 HAL固件库编程的文件构架

    对于我这种以前只接触过51和AVR单片机编程的小菜来说,现在开始学习STM32的编程,对于函数的功能以及C语言的语法都还好理解,难的是它提供的那一套硬件抽象层(HAL)驱动是怎么和其他的东东搭配在一起 ...

  8. Linux下TCP网络编程与基于Windows下C#socket编程间通信

    一.linux下TCP网络编程基础,需要了解相关函数 Socket():用于套接字初始化. Bind():将 socket 与本机上的一个端口绑定,就可以在该端口监听服务请求. Listen():使s ...

  9. .Net中的并行编程-6.常用优化策略

                本文是.Net中的并行编程第六篇,今天就介绍一些我在实际项目中的一些常用优化策略.      一.避免线程之间共享数据 避免线程之间共享数据主要是因为锁的问题,无论什么粒度的锁 ...

随机推荐

  1. Django微信小程序后台开发教程

    本文链接:https://blog.csdn.net/qq_43467898/article/details/83187698Django微信小程序后台开发教程1 申请小程序,创建hello worl ...

  2. Composer 安装 Jira API 库

    环境要求: PHP >= 5.5.9 php JsonMapper phpdotenv 安装 下载安装 Composer curl -sS https://getcomposer.org/ins ...

  3. PHP 输出两个指定日期之间的所有日期

    function printDates($start,$end){ $dt_start = strtotime($start); $dt_end = strtotime($end); while ($ ...

  4. Python之BeautifulSoup的使用示例

    import requests from bs4 import BeautifulSoup url = 'http://pm25.in/'+city_pinyin r = requests.get(u ...

  5. openresty开发系列27--openresty中封装redis操作

    openresty开发系列27--openresty中封装redis操作 在关于web+lua+openresty开发中,项目中会大量操作redis, 重复创建连接-->数据操作-->关闭 ...

  6. 六、postman做ui测试

    一.思路 发请求去拿到网站的响应——>html 解析html标签,判断一些元素是否显示 二.目的 快速检查ui是否正确 三.用到的库 Cheerio https://cheerios.js.or ...

  7. vs Qt mysql 打包程序 Driver not loaded Driver not loaded

    vs下开发Qt连接mysql程序,开发过程中操作MySQL没有问题,但打包以后安装在别的电脑上发现竟然无法连接MySQL,打包的时候,所需的libmysql.dll等dll文件拷贝到exe同级目录了, ...

  8. idea使用快捷键ALT+/的时候,本来想在new后面创建对象,结果又出来一个new

    我们知道eclipse的自动提示补齐new 后面的对象的快捷键是ALT+/,当我使用idea的时候,把idea的快捷键换成了eclipse的风格. 然而当我按下ALT+/的时候,就给我自动输入了一个n ...

  9. 【Leetcode_easy】876. Middle of the Linked List

    problem 876. Middle of the Linked List 参考 1. Leetcode_easy_876. Middle of the Linked List; 完

  10. 使用Matlab绘制三维图的几种方法

    以下六个函数都可以实现绘制三维图像: surf(xx,yy,zz); surfc(xx,yy,zz); mesh(xx,yy,zz); meshc(xx,yy,zz); meshz(xx,yy,zz) ...