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的導入表:

相關文章
相關標籤/搜索