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. Apollo简介及项目集成

    1. 产生背景 随着程序功能的日益复杂,程序的配置日益增多:各种功能的开关.参数的配置.服务器的地址…… 对程序配置的期望值也越来越高:配置修改后实时生效,灰度发布,分环境.分集群管理配置,完善的权限 ...

  2. SQLServer stuff函数

    STUFF ( character_expression , start , length ,character_expression ) 参数 character_expression 一个字符数据 ...

  3. linux: E: Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)

    今天在使用ubuntu执行下列指令的时候出现了错误: sudo apt-get update 解决办法: 输入以下命令: sudo rm /var/cache/apt/archives/lock su ...

  4. 从0开始学爬虫7之BeautifulSoup模块的简单介绍

    参考文档: https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/ # 安装 beautifulsoup4 (pytools) D:\pyt ...

  5. ckpt pb

    (t20190518) luo@luo-All-Series:/dev/disk_2019/mask_rcnn_20190518/Mask_RCNN_20190902/models/research$ ...

  6. Wpf 关闭当前窗体 打开新窗体

    MainWindow mainWindow = new MainWindow("/pages/ProductionInfo/ProductionFacts.xaml"); Wind ...

  7. django ORM 自定义字段

    class FixedCharField(models.Field): """ 自定义的char类型的字段类 """ def __init_ ...

  8. 全面系统Python3入门+进阶-1-8 Python的前景

    语言的热度. python在开发效率上有优势 大数据.人工智能 结束

  9. [Sklearn] Linear regression models to fit noisy data

    Ref: [Link] sklearn各种回归和预测[各线性模型对噪声的反应] Ref: Linear Regression 实战[循序渐进思考过程] Ref: simple linear regre ...

  10. (十四)访问标志 Access_flags

    一.概念 上一章节讲到了常量池,如下图,常量池之后便是访问标志acess_flags,占2个字节(u2). 二.例子 编写一个接口. public interface Test{ public fin ...