Windows下动态链接

        Dll即动态链接库,相当于Linux下的共享对象。Windows下的类ELF文件称为PE文件,它属于PE/COFF格式。

    PE里面有两个常用的概念,基地址和相对地址(RVA);当一个PE文件被装载时,其进程地址空间中的起始地址就是基地址,任何一个PE文件都有一个优先加载的基地址,PE文件头中的Image Base。

    通过简单示例,了解DLL的创建和使用,其中最基本的概念便是导出。
__declspec(export) double Add( double a, double b)
{
    return a + b;
} 
__declspec(export) double Sub( double a, double b)
{
    return a - b;
}
__declspec(export) double Mul( double a, double b)
{
    return a * b;
}
    使用VS2008编译器cl进行编译: $ cl /LDd Math.c
生成"Math.dll"、"Math.obj"、"Math.exp" 和 "Math.lib" 四个文件。通过dumpbin查看DLL的导出符号:
$ dumpbin /EXPORTS Math.dll


我们也可以采用模块定义文件(.def)声明DLL中某个函数为导出符号,以代替使用“__declspec(export)”扩展:
LIBRARY Math
EXPORTS
Add
Sub
Mul
$ cl /LD /DEF Math.def Math.c
该种方法和 使用“__declspec(export)”扩展作用相同:


当然,我们也可以使用这种方式将导出函数重新命名:
LIBRARY Math
EXPORTS
add = Add
Sub
Mul

    使用DLL的过程其实就是引用DLL中的导出函数和符号的过程,即导入过程。对于从其他DLL导入的符号,我们需要使用“__declspec(dllimport)”显示地声明某个符号为导入符号:
#include <stdio.h>
 
__declspec(import) double Sub( double a, double b);
 
int main()
{
    double result = Sub(3.0, 2.0);
    printf("Result = %f\n", result);
    return 0:
}
$ cl /c TestMath.c
$ link TestMath.o Math.lib
......
    Math.lib并不包含Math.c的代码和数据,它用来描述Math.dll的导出符号,它包含了TestMath.o链接Math.dll时所需要的导入符号以及一部分桩代码;Math.lib又被称为导入库。

    与ELF文件类似,DLL也支持运行时链接,即运行时加载,一个简单示例:
#include <windows.h>
#include <stdio.h>

typedef (*Func)(double, double);
 
__declspec(import) double Sub( double a, double b);
 
int main()
{
    Func func;
 
    // Load DLL
    HINSTANCE hinstLib  = LoadLibrary("Math.dll");
    if (NULL == hinstLib){
        printf("ERROR: unable to load DLL\n");
        return 1;
    }
 
    // Get function address
    function = (Func)GetProcAddress(hinstLib, "Add");
    if (NULL == function){
        printf("ERROR: unable to find DLL function\n");
        FreeLibrary(hinstLib);
        return 1;
    }
 
    // Call function
    result = function(1.0, 2.0);
 
    // Unload DLL file
    result = function(1.0, 2.0);
    FreeLibrary(hinstLib);
 
    // Display result
    printf("Result is %f\n", result);

    return 0:
}




你可能感兴趣的:(动态链接)