您的位置:首页 > 运维架构 > Linux

Windows系统和Linux系统中的静态链接库与动态链接库(一)

2010-12-01 01:00 441 查看
最近突然想写一个跨平台的项目,发现首先第一个要解决的调用跨平台的库的问题,所以研究一把两个平台下的库的问题。本文主要讲述在Windows系统和Linux系统的两种操作系统中,如何来建立静态链接库与动态链接库。
1.介绍
1.1 为什么要使用库(静态链接库与动态链接库)?
基于提高代码的重用性、可维护性、可测试性等包含但限于上述原因,软件设计一般就会就功能分类,形成模块化。库则是模块化开发的体现,它封装具有分类功能的代码,供其他模块来调用。
1.2 什么是静态链接库与动态链接库?

概念无法来严谨描述,但无论是在Windows系统还是在Linux系统中,思想基本一致。如果在程序中调用了静态链接库中的函数,则被调用的函数的代码(确切的说是编译后的二进制映像代码而不是源代码)需要嵌入到程序中去一起编译,与程序形成一个整体。很显然,调用静态链接库的程序文件大小要变大一些。在Windows系统中,其后缀名一般为.lib,在Linux系统中,其后缀名一般为.a。如果在程序中调用了动态链接库中的函数时,动态链接库只需要在内存中保存一份,供所有需要的程序来调用。在Windows系统中,其后缀名一般为.dll,在Linux系统中,其后缀名的格式一般为.so.x.x。本文来论述Windows系统中的dll文件时,只提一种Non-MFC DLL,即非MFC动态库,而不涉及另外两种(MFC Regular DLL与 MFC Extension DLL)
一般来说,动态链接库使用的更广泛一些,所以重点关是动态链接库。

2.Windows系统中的静态链接库与动态链接库

2.1 Windows系统中的静态链接库
通过创建一个简单的静态链接库,使用C语言,开发工具为Visual Studio 2010,操作系统为Windows 7.
(1)创建一个空项目,命名为TestStaticLibProject,在项目属性中更改如下图红色标记的属性,如下图:



(2)创建头文件static_lib.h和源文件static_lib.c,代码分别如下:

#ifndef _STATIC_LIB_H
#define _STATIC_LIB_H

/* 导入或是导出的函数声明 */
void test_static_lib_method(void);

#endif


/*静态链接库对外提供的函数*/
#include <stdio.h>

/*通过该宏定义来将头文件的函数声明为导出函数*/
#include "static_lib.h"

void test_static_lib_method(void)
{
printf("test static library method./n");
}


(3)运行,则可得到TestStaticLibProject.lib,就是静态链接库。

2.2 Windows系统中的动态链接库
通过创建一个简单的动态链接库,步骤如下:

(1)创建一个空项目,命名为TestDynamicLibProject,在项目中更改其输出,如下图:



创建头文件dynamic_lib.h和源文件dynamic_lib.c,代码分别如下:
/*dynamic_lib.h*/

/******************************************************************************
在两个工程项目中使用该头文件:
(1)动态链接库工程项目(也就是本项目)
(2)引用动态链接库的工程项目
******************************************************************************/
#ifndef _DYNAMIC_LIB_H
#define _DYNAMIC_LIB_H

/********方案一:使用_declspec关键字导出函数*****************************************************
//导入或是导出动态链接库中函数的前缀
#ifdef DYNAMIC_DLL
#ifdef __cplusplus
#define EXTERN extern "C" _declspec(dllexport)
#else
#define EXTERN extern _declspec(dllexport)
#endif
#else
#define EXTERN extern _declspec(dllimport)
#endif

//导入或是导出的函数声明
EXTERN void test_dynamic_lib_method(void);
*************************************************************************************************/

/********方案二:使用.def文件导出函数*************************************************************/
void test_dynamic_lib_method(void);
/*************************************************************************************************/
#endif


/*dynamic_lib.c*/
/*动态链接库对外提供的函数*/
#include <stdio.h>

/*通过该宏定义来将头文件的函数声明为导出函数*/
//#define DYNAMIC_DLL
#include "dynamic_lib.h"

void test_dynamic_lib_method(void)
{
printf("test dynamic library method./n");

}


(2)从DLL导出函数有两种方法:

1. 在导出函数中定义extern _declspec(dllexport) ,可以见头文件和源代码的方案一。顺便提一句,如果是C++,需要导出类,则在头文件中的类的声明中使用类似的格式,例如:class _declspec(dllexport) Point 。

2. 创建模块定义文件(.DEF)并在建立DLL时使用.DEF文件。

简单的描述一下如何创建.DEF文件
(1)第一行必须使用关键字LIBRARY描述DLL的名字,举例:
LIBRARY libcstl
(2)第二行可以是EXPORTS关键字,一看就知道是要导出函数了。EXPORTS后面是“函数名称”和“导出函数的数字”(它是由“@”符号与数字构成),“导出函数的数字”如果省略则编译器会自动生成。举例导出三个函数如下:
_type_register @1000
_type_duplicate @1001
_type_debug @1002

(3)其他的:注释可以使用分号“;”来完成;VERSION关键字可以指定版本号,DESCRIPTION一句可以描述DLL的用途。

(3)运行,则可得到TestDynamicLibProject.dll和TestDynamicLibProject.lib,就是动态链接库。

这两个导出方法在某些场合各有各的用途,比如第一种就适合在VC项目中自己调用,第二种适合在跨平台中,或是跨语言中使用。

2.3 测试项目

以上创建了两个链接库,可以在项目中来使用。创建一个名为TestProject的空项目(Empty Project),然后引用上面的两个库,步骤如下:

(1) 引用静态库:在下图的输入框输入静态库的名称。



(2)引用动态库,除了在上面的图中动态库对应的lib的名称(它里面包含标识符),还需要如下图中填上动态链接库的所在目录:



(3)调用库的项目代码如下,名称为main.c:
#include <stdio.h>
#include <stdarg.h>

#include "local_method.h"
#include "../TestDynamicLibProject/dynamic_lib.h"
#include "../TestStaticLibProject/static_lib.h"

int main()
{

printf("Hello, World./n");

/*(1)测试本地的方法*/
test_local_method();

/*(2)测试动态链接库的方法*/
test_dynamic_lib_method();

/*(3)测试静态态链接库的方法*/
test_static_lib_method();

getchar();

return 0;


提供该项目源代码下载,关于Linux的部分下次再写吧。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: