Windows动态库学习心得

  最近在工做中须要给项目组其余成员提供调用函数,决心抛弃之前“拷贝头文件/源文件”的简陋方法,采用动态库的方式对本身开发的接口进行模块化管理。因以前一直没有机会从事Windows动态库的开发,现借助这个开发任务,恶补了《程序员的自我修养》这本书,并经过动手实践+上网找资料的方式,学习了Windows DLL的工做原理、常见用法。本篇分为4个部分:DLL实例演示;DLL显示运行时连接;符号导入导出表;DLL优化。程序员

一、DLL实例演示windows

(a)建立一个简单的DLLide

  • 编写代码
_declspec(dllexport) double Add(double a, double b)
{

    return a + b;
}

_declspec(dllexport) double Sub(double a, double b)
{

    return a- b;
}

_declspec(dllexport) double Mul(double a, double b)
{
    return a * b;
}
View Code
  • 使用MSVC的编译器CL进行编译

  

(b)建立测试程序,使用DLL模块化

  • 编写代码
#include <stdio.h>

_declspec(dllimport) double Sub(double a, double b);

void main()
{
    double result = Sub(3.0,2.0);
    printf("Result = %f\n",result);
}
View Code
  • 进行编译、连接、执行

 

(c)使用模块定义文件生成DLL函数

  • 修改代码,去除_declspec(dllexport):
double Add(double a, double b)
{

    return a + b;
}

double Sub(double a, double b)
{

    return a- b;
}

double Mul(double a, double b)
{
    return a * b;
}
View Code

 

  • 编写模块定义文件Math.def
LIBRARY Math

EXPORTS

Add
Sub
Mul
View Code

 

  • 从新编译Math.c文件

  • 从新连接TestMath.obj和Math.lib——link TestMath.obj Math.lib

二、DLL显示运行时连接工具

  Windows中提供3个API进行动态库的运行时加载:学习

    1. LoadLibrary——装载一个DLL到进程的地址空间;
    2. GetProcAddress——查找某个符号(函数)的地址;
    3. FreeLibrary——卸载装载到进程中的DLL。
  • 编写代码
#include <windows.h>
#include <stdio.h>

/*
*    Description:    申明一个函数指针,要求其输入两个double数据,返回一个double
*/
typedef double (*Func)(double,double);

void main()
{
    Func function;
    double result;

    //加载动态库
    HINSTANCE hinstLib = LoadLibrary("Math.dll");
    if (hinstLib == NULL)
    {
        printf("错误:不能加载动态库\n");
        return;
    }

    //获取动态库中函数地址
    function = (Func)GetProcAddress(hinstLib,"Add");
    if (function == NULL)
    {
        printf("错误:不能找到Add函数\n");
        //出错调用,需释放动态库
        FreeLibrary(hinstLib);
        return;
    }

    //执行动态库函数
    result = function(1.0,2.0);

    //出错调用,需释放动态库
    FreeLibrary(hinstLib);

    //显示结果
    printf("Result=%f\n",result);
}
View Code

 

  • 编译,执行

三、符号导入导出表测试

一、打开Microsoft Visual C++6.0 Tools——>Depends,将生成的Math.dll拖入其中,即可以查看动态库导出的函数优化

二、使用dumpbin,根据参数/EXPORTS,显示导出函数表spa

三、使用dumpbin,根据参数/IMPORTS,显示导入函数表

四、DLL优化

  导入函数绑定——若是程序运行时,其依赖的DLL都以一样的顺序装载到一样的内存地址,那么他们的导出符号的地址是不变的。所以能够考虑将这些导出函数的地址保存至执行程序的导入表中,这样程序每次启动时均可以省去符号解析的过程。

  • 使用工具editbin对TestMath.exea进行绑定:

  • 查看绑定后TestMath.exe的导入表:

相关文章
相关标签/搜索