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 ...
随机推荐
- java的主函数中各个词的作用
主函数 public static void main(String[] args){} public: main主方法是由jvm(虚拟机)来调用,jvm实际也是一程序,为了保证jvm能在任何情况下调 ...
- SQL用replace替换文本部分内容
替换文本内容 update tk_question set stem=replace(cast(stem as varchar(max)) ,'被替换文本','替换文本') 查询字段内容长度 sele ...
- 推荐一个可视化的学习Git的好网站:LearnGitBranching
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:推荐一个可视化的学习Git的好网站:LearnGitBranching.
- Linux防火墙iptables学习笔记(三)iptables命令详解和举例[转载]
Linux防火墙iptables学习笔记(三)iptables命令详解和举例 2008-10-16 23:45:46 转载 网上看到这个配置讲解得还比较易懂,就转过来了,大家一起看下,希望对您工作能 ...
- Char* ,CString ,WCHAR*之间的转换
关于Char* ,CString ,WCHAR*之间的转换问题 GDI+所有类的接口函数如果要传递字符串作为参数的话,似乎都用UNICODE串,即WCHAR*.我开始也被整得晕头转向,因为窗口编程所用 ...
- Codeforces 417E Square Table(随机算法)
题目链接:Codeforces 417E Square Table 题目大意:给出n和m.要求给出一个矩阵,要求每一列每一行的元素的平方总和是一个平方数. 解题思路:构造.依照 a a a b a a ...
- PHP文件头部(header)解释
1. Accept:告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type. 2. Accept-Charset: 浏览器申 ...
- 输入一个字符串,去掉重复的字符,并按ASCII值排序-华为机试
import java.util.Scanner; //输入字符串,去掉重复的字符,并按ASSIC码值排序 public class quChong { public static void main ...
- android线程与线程池-----线程池(二)《android开发艺术与探索》
android 中的线程池 线程池的优点: 1 重用线程池中的线程,避免了线程的创建和销毁带来的性能开销 2 能有效的控制最大并发数,避免大量线程之间因为喜欢抢资源而导致阻塞 3 能够对线程进行简单的 ...
- Android 解决调用系统相册打不开图片 DecodeServices报解码错误
这是由于系统相册不知道你图片目录是一个相册.打开前需要向系统相册“注册一下”,说白了就是让系统相册知道你这个图片所在的文件夹是个相册. private static void scanImageFil ...