首页 > 代码库 > static and dynamic lib

static and dynamic lib

Windows下的dll和lib

 

简介

DLL就是动态链接库 LIB是静态链接库

DLL是程序在运行阶段才需要的文件

LIB是程序编译时需要链接的文件

 

使用静态库

静态库实际上是obj文件打包而成

使用静态库时 在程序中加入

#pragma comment(lib, "WSock32.lib")

或者通过编译器项目设置中 手动添加Lib静态库

这样在链接程序 就会将静态库链接到程序里面 生成一个可执行文件或其他目标文件

 

使用动态库

动态库是一个标准的PE文件 经过编译器编译链接的

动态库一般会有两个文件 ws32.dll ws32.lib

这里的lib并不是上面介绍的静态库 他只包含了一些跳转指令

真正的执行命令在dll中

动态库的使用有两种方式

 

一是有系统负责加载dll

这种方式调用dll时 需要在程序编译时将lib链接到程序中

就像添加静态库一样

程序运行时 系统加载dll 执行dll中命令

 

二是显示加载dll

这种方式调用不需要lib文件

程序运行时 使用loadlibrary等api 显示加载dll

取得里面的函数指针 调用

 

动态库函数的导出

这里只介绍两种方式

一是使用模块定义文件(.def文件) 二是使用__declspec(dllexport)关键字

   

使用.def文件导出

优点:

1、能控制导出函数名字 在导出C++函数时 可以控制函数名不出现乱码 如func@123axx

2、你能控制导出函数的序号

特别适用于第三方DLL的制作

def文件格式:

LIBRARY dll名称

EXPORTS

func1 @1

func2 @2

把def文件和代码放在同一级目录下 编译dll时 会自动载入def生成dll

 

使用__declspec(dllexport)

优点是简单 方便 但无法完成上面.def的工作 一般用于应用程序自己使用的DLL

当DLL更新后 要使用新的DLL 也需要应用重新编译链接

 

Dll中设置共享可读写变量

Dll中全局变量是可以供多个进程共享的 但如果有一个进程修改了

Dll会使用页面拷贝机制 为该进程维护一个单独的页面 将原有原有数据拷贝过来

然后修改为该进程的值

这样其他进程依然使用原来的页面 所有这个进程对变量的修改 不会影响其他进程

 

如果我想设置一个变量 让一个进程修改他的值 其他进程也能看到

则必须建立一个共享的节 将共享变量放到节中 告诉dll 这里的东西是共享的

如果我改变他 不要使用页面拷贝机制

 

创建节的方法(放在原代码文件中):

#pragma data_seg("MySec") //MySec是新创建的节的名字(不能超过8个字节)

HWND g_hWnd=NULL;  //新变量必须初始化,否则没有新建节的信息

#pragma data_seg()   //以上为新建节

 

新创建的节 共享后才有效 共享的两种方法

1、#pragma comment(linker,"/section:MySec,RWS")  //设置节的属性,读,写,共享

2、也可以把#pragma comment(linker,"/section:MySec,RWS")省略。

在.def文件中添加如下代码:

SEGMENTS

MySec read write shared

也能对节的属性进行设置

 

 

Linux 下的.so .a

 

.a静态库 使用ar命令将一个或多个.o文件打包成.a文件

编译时使用 –llib链接

 

.a静态库的生成

ar cru libxxx.a x.o xx.o xxx.o

ranlib libxxx.a                #更新静态库函数表

 

动态库使用gcc编译生成

 

gcc –shared –fPIC xx.c –o libxx.so