Windows动态库管理(一)

来源:互联网 发布:域名备案系统 编辑:程序博客网 时间:2024/05/25 08:11

动态库的隐式链接


Windows动态库的使用分为隐式链接和显示链接,本文简单介绍隐式链接:

    

     符号导出:

        动态库分为内部调用内容和导出内容(PS:内容包括数据结构,类,变量,函数等),动态库的导出内容才是动态库存在最主要的意义,当然动态库也可以没有导出内容,纯粹用来装载各种资源,这在隐式链接中完全没有意义(PS:加载资源的时候需要获得模块的句柄,目前我还没有发现获得模块句柄的方法),隐式链接的导出分为两种方式,一种是_declspec导入导出,一种是def文件,_declspec头文件如下代码所示:  //Mylib.h

#ifdef ImplicitLink#define MYLIB extern "C" _declspec(dllexport)class _declspec(dllexport) CDllClass;#else#define MYLIB extern "C" _declspec(dllimport)class _declspec(dllimport) CDllClass;#endifMYLIB void Add(int i, int j);

        其中函数为了兼容不容的编译器,C和C++,必须在前面申明extern "C", 动态库中所有与导出符号的实现有关的CPP文件都必须包含这个头文件,并且宏定义ImplicitLink,代码示例如下:.cpp

#define ImplicitLink#include "MyLib.h"void Add(int i, int j){    printf("Sum = %d\n", i +j);}class  CDllClass{public:    CDllClass()    {        printf("创建\n");    }};

当定义ImplicitLink时,头文件中申明为导出,也就是_declspec(dllexprot),没有定义这个宏的时候,头文件中符号为导入_declspec(dllimport),这样定义写的好处是别人在使用你的动态库的时候不需要再去考虑导入导出,直接包含头文件就好了。


      def文件相对来说简单一些,需要额外的新建一个def文件,def的格式如下:.def文件

         

LIBRARY"DefDll"EXPORTSAdd @1i @2
exprotes下面是具体的导出符号名字,导出符号后面跟序号,序号标识动态库中导出符号的索引,在显示链接的时候会用得到。

        头文件的申明如下,没有关于_declspec的使用了,直接就是普通的申明 //Mylib.h

      

void Add(int i, int j);extern int i;

        同样动态库中关于导出符号实现或者定义的地方都需要添加这个头文件 .cpp

#include "MyLib.h"int i = 10;class  CDllClass{public:    CDllClass()    {        printf("创建\n");    }};void Add(int i, int j){    printf("Sum = %d\n", i +j);}
       使用def文件有个不好的地方就是导出类或者结构体之类的数据结构会比较麻烦,我目前还没有实现,有人说可以实现,不过出于字节对齐等方面的考虑我们一般不要导出数据结构,直接封装成函数在动态库内操作。


    隐式链接

当动态库至少导出一个符号时,会产生一个lib文件,lib文件在我们使用动态库时需要使用,我们使用下面语句来导入动态库符号:

        #pragma comment(lib, "MyLib.lib");

       lib文件只是包含了动态库中的导出符号,所以这个时候二进制文件.dll还是需要的,当另一个模块刚启动的时候,它会查看自己的导入符号表,把所有需要动态库加载到当前的进程地址空间,这个过程是由C/C++运行库完成的,具体的顺序比全局变量定义还要提前一点。

     隐式链接动态库代码示例:

   

#include "MyLib.h"//#pragma  comment(lib, "DeclspecDllExprot.lib")#pragma comment(lib, "DefDll.lib")int _tmain(int argc, _TCHAR* argv[]){    printf("ready\n");    Add(10, 20);    i = 10;    getchar();        return 0;}

原创粉丝点击