最近在工做中須要給項目組其餘成員提供調用函數,決心拋棄之前「拷貝頭文件/源文件」的簡陋方法,採用動態庫的方式對本身開發的接口進行模塊化管理。因以前一直沒有機會從事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; }
(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); }
(c)使用模塊定義文件生成DLL函數
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; }
LIBRARY Math
EXPORTS
Add
Sub
Mul
二、DLL顯示運行時連接工具
Windows中提供3個API進行動態庫的運行時加載:學習
#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); }
三、符號導入導出表測試
一、打開Microsoft Visual C++6.0 Tools——>Depends,將生成的Math.dll拖入其中,即可以查看動態庫導出的函數優化
二、使用dumpbin,根據參數/EXPORTS,顯示導出函數表spa
三、使用dumpbin,根據參數/IMPORTS,顯示導入函數表
四、DLL優化
導入函數綁定——若是程序運行時,其依賴的DLL都以一樣的順序裝載到一樣的內存地址,那麼他們的導出符號的地址是不變的。所以能夠考慮將這些導出函數的地址保存至執行程序的導入表中,這樣程序每次啓動時均可以省去符號解析的過程。