动态链接库基础学习二

动态加载动态链接库

使程序在需要时加载动态链接库时加载。尤其是很多动态链接库需要调用时,大大的加快了程序启动的时间。比隐式连接动态链接库更节省内存资源。

首先我们接着重写上次add按钮的代码:

 void CDllTestDlg::OnBtnAdd()

{

       // TODO: Add your control notification handler code here

    //动态加载Dll

       HINSTANCE hInst=LoadLibrary("Dll2.dll");

    typedef int (*ADDPROC)(int a,int b);

       ADDPROC Add=(ADDPROC)GetProcAddress(hInst,"add");

       if(!Add)

       {

              MessageBox("获取函数地址失败!");

              return;

       }

       CString str;

       str.Format("5+3=%d,",Add(5,3));

       MessageBox(str);

    FreeLibrary(hInst);

 

}

看到这些代码我们首先分析其中的函数:

1,动态加载动态链接库函数:(看到这个函数,我们想到LoadIconLoadResource…

HMODULE LoadLibrary(

  LPCTSTR lpFileName   // file name of module

);

HMODULE:即模块句柄,这里是实例句柄,MSDN详细,可查阅之。

2.我们这里又定义了一个函数指针类型(*ADDPROC)。用typedef 来定义,ADDPROC来接收GetProcAddress返回的函数地址。

typedef int (*ADDPROC)(int a, int b);

此定义也可看做一个函数,其返回值为int型,且有两个int型的参数。

这里可能有些不懂,那么我们想想:

int add(int a, int b)在存储器中是怎样存储的,我们可以这样假设:

add只是代表一个地址,表示这个函数结构的地址

这个结构中有两个int4bytes)类型的参数ab(共占了8bytes)。

那么有人要问了,那返回值呢??

我是这样想的的:函数的参数经过CPU的运算,得到的结果都放进了EAX中,程序要用时只需要把它放到存储器的指定的地址即可。

3.此函数来获取导入函数地址。

FARPROC GetProcAddress(

  HMODULE hModule,    // handle to DLL module

  LPCSTR lpProcName   // function name

);

其中FARPROC表示得到指定函数的地址。我们可以用自己定义的ADDPROC来接收此地址

理解了以上函数,我们基本掌握了动态加载的精华。

 

为了程序拥有容错的能力。我们判断了ADD是否为空,来处理错误。

 

这里注意2个问题:

1 当我们把Dll2.dll的调用约定发生变化时,Dll2的导出函数名不发生变化。但是测试程序动态加载时,必须与Dll2.dll中的调用约定保持一致。

int _stdcall add(int a, int b)

{

    return a+b;

}

那么:

typedef int (_stdcall *ADDPROC)(int a,int b);

2

还记得用dumpbinDll2.dll导出函数吗??

这里我们可以看到addsubtract分别有一个序号 1 2

GetProcAddress函数中也可以通过导入函数序号来访问函数:

ADDPROC Add=(ADDPROC)GetProcAddress(hInst,MAKEINTRESOURCE(1));

其中MAKEINTRESOURCE宏使一个整形值转变成一个与函数需要相比配资源形式。这里转化成add(即所需要调用的的函数名)。

 

学习完这些,我们基本上可以编写简单的DLL了。若想精通DLL编写,我们还得继续努力。 http://www.cnblogs.com/fangyukuan/archive/2010/06/21/1761666.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值