C++ 静态、动态链接库的简单实现
一、什么是静态链接库,什么是动态链接库?
1、静态链接库就是你使用的.lib文件,库中的代码最后需要连接到你的可执行文件中去,所以静态连接的可执行文件一般比较大一些。在静态库情况下,函数和数据被编译进一个二进制文件(通常扩展名为*.LIB),Visual C++的编译器在链接过程中将从静态库中恢复这些函数和数据并把它们和应用程序中的其它模块组合在一起生成可执行文件。这个过程称为“静态链接”。
如果采用静态链接库,则无论你愿不愿意,lib 中的指令都全部被直接包含在最终生成的 EXE 文件中了。
可以参考:http://www.cnblogs.com/Winston/archive/2008/07/05/1236273.html
1.1 windows下的静态链接库
1、通用:
格式如下:#prama comment(lib,"XXX.lib")
2、针对开发环境:
- 如果使用Visual C++:可以在Project Setting-->Link中加入你的静态库,也可以直接把该.lib文件加入到你的工程中。
- 如果使用Visual Studio,位置在 项目→配置属性→连接器→输入→附加依赖项 中加入.lib文件。
2、动态链接库英文为DLL,是Dynamic Link Library的缩写形式。所谓动态链接,就是把一些经常会共用的代码制作成DLL档,当可执行文件调用到DLL档内的函数时,windows操作系统才会把DLL档加载存储器内,DLL档本身的结构就是可执行文件,当程序需求函数才进行链接。通过动态链接方式,存储器浪费的情形将可大幅降低。
动态链接库的加载方式分为两种:静态加载、动态加载。
2.1 静态加载
1、需求:
- 服务端的头文件
- 服务端所产生的lib文件和dll文件
2、客户端加载:
- #prama comment(lib,"XXX.lib")
2.2 动态加载
1、需求:
- 服务端所产生的dll文件
2、客户端加载:三步曲
- LoadLibrary("DyLinkLib.dll")
- GetProcAddress(hmod,"add");
- FreeLibrary(hmod);
二、代码示例
1、静态链接库:
- 服务端:工程名为StaticLibrary
StaticLib.h:
#ifndef ADD_H_
#define ADD_H_
int add(int a, int b);
#endif
StaticLib.cpp: int add(int a, int b)
{
return a+b;
}
产生:StaticLibrary.lib
- 客户端:首先得将服务端的StaticLib.h头文件和StaticLibrary.lib文件发送给客户,这时客户端才能调用我们编写的静态链接库。
#include "StaticLib.h"
#include <iostream.h> #pragma comment(lib,"StaticLibrary.lib")
//这里的lib好像过滤器功能,告诉编译器要使用lib文件,其次通过"StaticLibrary.lib"名字查找
int main(void)
{
cout << add(,) << endl;
return ;
}
这里的静态链接库的链接采用windows平台静态链接的通用方式。
小结:静态链接库的编写和普通函数的编写一样,没什么特大的区别
2、动态链接库
- 静态加载方式
- 服务端
DystaticLink.h #ifdef MY_ADD
#define ADD_H extern "C" _declspec(dllexport)
#else
#define ADD_H extern "C" _declspec(dllimport)
#endif ADD_H int add(int a,int b);
DystaticLink.cpp #define MY_ADD
#include "DystaticLink.h" int add(int a,int b)
{
return a+b;
}
- 客户端
#include <iostream.h>
#include "DystaticLink.h" #pragma comment(lib,"DystaticLink.lib") int main()
{
cout << add(,);
return ;
}
小结:动态库的静态加载,需要服务端的"DystaticLink.h"头文件,以及服务端产生的DystaticLink.lib和DystaticLink.dll文件。
2、动态加载
动态加载可以参照:http://blog.sina.com.cn/s/blog_69e905cd0100m8zq.html
- 服务端
DyLinkLib.h: #ifdef ADD_H_
#define ADD_H extern "C" _declspec(dllexport)
#else
#define ADD_H extern "C" _declspec(dllimport)
#endif ADD_H int add(int a,int b);
DyLinkLib.cpp #define ADD_H_
#include "DyLinkLib.h" int add(int a,int b)
{
return a+b;
}
- 客户端
#include <iostream.h>
#include <windows.h> int main(void)
{
HMODULE hmod = LoadLibrary("DyLinkLib.dll");
if (!hmod)
{
cout << "加载失败" << endl;
return ;
}
typedef int (*AddProc)(int a, int b);
AddProc pAdd = (AddProc)GetProcAddress(hmod,"add");
if (!pAdd)
{
cout << "获取地址失败!" << endl;
return ;
}
cout << pAdd(,) << endl;
FreeLibrary(hmod);
return ;
}
- 解析:首先看一下大致流程
LoadLibrary
The LoadLibrary function maps the specified executable module into the address space of the calling process. For additional load options, use the LoadLibraryEx function. HMODULE LoadLibrary(
LPCTSTR lpFileName // file name of module
);1、LoadLibrary返回了模块句柄,这时,我们可以利用GetProcAddress函数得到动态库的某个函数地址。
GetProcAddress
The GetProcAddress function retrieves the address of an exported function or variable from the specified dynamic-link library (DLL). FARPROC GetProcAddress(
HMODULE hModule, // handle to DLL module
LPCSTR lpProcName // function name
);2、GetProcAddress函数返回一个函数指针,为了接收这个函数指针,我们的定义一个函数指针类型,这个函数指针类型要与要加载的动态库里的函数类型一致,此外还得将GetProcAddress返回值强制转换一下。
typedef int (*AddProc)(int a, int b);
AddProc pAdd = (AddProc)GetProcAddress(hmod,"add");3、得到了函数指针,我们就可以利用这个函数指针调用动态库的指定函数
cout << pAdd(,) << endl;
4、释放加载的动态库
FreeLibrary(hmod);
小结:动态加载时,只需服务端发送DyLinkLib.dll文件即可。
C++ 静态、动态链接库的简单实现的更多相关文章
- C++高级编程2. 静态动态链接库
C++高级编程2. 静态动态链接库20131018 1.动态链接库和静态链接库的区别: 静态链接库就是把lib文件中用到的函数代码直接连接进目标程序,程序运行的时候不在需要其他的库文件:动态链接库是把 ...
- 详谈 Java工厂 --- 静态工厂 【简单工厂模式】
1.前言 什么是工厂模式? 就是为了尽可能将代码的耦合度降低而产生的设计模式. 这篇随笔讲解静态工厂的思路和具体操作. 2.总结 (1)静态工厂又称 简单 工厂模式 ,是最最简单的工厂模式. (2)优 ...
- mfc显示静态图片最简单的方法
一致都是研究如何调用opencv显示动态图片,但是很多时候在显示图标的时候,都是需要显示静态图片,现在将最简单的方法总结下: 1.添加picture控件 2.添加资源,要求为bmp 3.修改属性 结果 ...
- jsp静态化之简单介绍
package com.zwd.text; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputS ...
- linux gcc 静态 动态链接库
静态链接库 首先生成依赖函数的目标文件 gcc -c source1.c source2.c; 然后归档目标文件到静态库 ar -rcs libYourID.a obj1.o obj2.o; 然后我们 ...
- rest-assured之静态导入及简单使用实例
一.静态导入 为了有效的使用rest-assured,官网推荐从下列class中静态导入方法: io.restassured.RestAssured.* io.restassured.matcher. ...
- PHP 中的静态变量的简单使用
静态变量的初始化只能在第一次static 声明的时候进行,这些静态变量只能在声明他的函数中访问到. 例如: <?php function do_something(){ static $firs ...
- C#中静态类、静态方法和静态变量的简单说明
静态方法与静态变量一样,属于类本身,而不属于哪个类的一个对象.调用一个被定义为static的方法,只有通过在它前面加上这个类的名称.一般定义里说是可以通过实例调用的.其他语言我还没测试,但是在C#中是 ...
- nginx静态资源服务器简单配置
有时候我们可以把服务器的一些文件放在固定目录以便下载,比如image,css,js等.就可以使用nginx转发静态资源. 参考链接:https://blog.csdn.net/name_is_wl/a ...
随机推荐
- [SDOI2015]权值
问题描述: 有一个长度为n的实数序列,,下标从1开始,其中第k个位置的实数为p · (sin(a · k + b) + cos(c · k + d) + 2),sin和cos采用弧度制,其中p,a,b ...
- 2D游戏编程4—Windows事件
windows消息传来的参数分解: Message: WM_ACTIVATE Parameterization: fActive = LOWORD(wParam); // act ...
- 上海Uber优步司机奖励政策(2月1日~2月7日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- 【转】shell 教程——02 几种常见的Shell
上面提到过,Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本. Unix/Linux上常见的Shell脚本解释器有bash.sh.csh.ksh等,习惯上把它们称作一种Shell.我们常说 ...
- BAT-使用BAT方法判断网络启动EXE(快捷方式)
原理思路:先启动iNode,如果访问www.baidu.com成功,证明网通了,这时就启动GXT和邮件等.PS:因为对BAT不清楚,所以自己写的东东可能有问题,希望大家有了解BAT的,看一下是否正 ...
- Java反射机制学习
Java 反射是Java语言的一个很重要的特征,它使得Java具体了“动态性”. 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法?答 ...
- PAT 1026. Table Tennis
A table tennis club has N tables available to the public. The tables are numbered from 1 to N. For ...
- jetty服务器
1,http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin 2,http://wiki.eclipse.org/Jetty#Getting_S ...
- 深入了解Angularjs指令中的ngModel
关于AngularJs的指令的知识学习,请参考... 这次我们接上次没讲完的知识继续. 前端人员在设计表单逻辑时, 在大部分情况下,我们需要为表单定义很多指令, 比如比较两个input内的值是否相同, ...
- SSH服务
基于Linux的服务器有多个网卡,其中一个网卡连接了网线,通过该网线链接了个人PC.PC上启动Vmware虚拟机,启动ubuntu系统.然后设置PC的网络为自动获取IP,在PC的Linux的Ubunt ...