/*win32 靜/動態庫製作與使用*/
chinanetboy
.dll 和.lib 都是程序集合,便於代碼重用。都是二進制的文件。 .
dll 也叫動態鏈接庫,與程序鏈接的方式爲運行時鏈接(run-time linked ),爲PE (portable executable )格式,也就是程完整的程序。.
exe 、.dll 、.fon 、.mod 、.drv 、.ocx 等等都是動態鏈接庫。如.exe 爲系統調用的函數集合。.
dll 不存在同名引用,且有導出表,與導入表。
.lib 也叫靜態鏈接庫,在編譯時與程序鏈接(link-time linked ),將“嵌入”到程序中。
會有冗餘(程序文件代碼的冗餘和運行時內存存儲的冗餘),當兩個lib 相鏈接時地址會重新建立同。
在使用.lib 之前,要在程序源代碼中引用lib 對應的頭文件.h ,這些頭文件告訴編譯器.lib 中有什麼。
在生成.dll 時,通常會生成一個.lib 。這個.lib 將被編譯到程序文件中,在程序運行的時候,告訴操作系統將要加載的.dll 。
這個.lib 包括對應.dll 的文件名、順序表(ordinal table 包含.dll 暴露出的函數的進入點),在程序運行的時候,通過順序表實現函數的跳轉。
如果不想使用或者找不到該.lib ,可以用LoadLibrary () Win32 API 和GetLibrary () Win32 API 。
VC IDE 爲了實現程序調試,會生成.PDB (程序數據庫,二進制),裏面包含源文件調用的文件信息和行信息。這樣就可以逐行調試了。
打開.lib ,查看其ascii 碼,可以看到如@@My_Function1123 的函數名,這些名稱在編譯時被編譯器運用mangling mechanism 進行了名稱的mangling 。
在程序的編譯過程中,如果出現如下錯誤“unresolved symbol 通常是因爲找不到引用過的外部函數對應的.lib 文件,或者是.c 、.cpp 源文件。
如果在c++ 工程中使用用c 編寫的.lib 文件,需要做如下引用:
extern “C ” { #include “headfile.h ” }
dll---com 組件dll ,__ 常規dll___win32 dll ,___mfc dll ,___extended dll (所有dll 不參與編譯)
lib | 與obj 文件類似的未編譯過符號文件,與obj 文件區別是聲明瞭轉入轉出函數
****************************************************************************************************
chinanetboy say:
談發佈lib,dll 的區別
發佈lib 庫時,我們通常也要把這個庫對應的頭文件也一起發佈,以方便別人使用你的LIB ,在wind32 彙編程序,
MS 把所有的API 函數是放在幾個大的*.LIB 中,另外還提供一對應的幾個*.inc ,實際上它如同*.h 頭文件,起到聲明API 函數的目的
發佈DLL 庫時,我們要公開這庫裏面所有的導入導出函數的函數聲明原形,以方便別人使用你的DLL ,
目前WINDOW 實現的就是以一些DLL 文件方式提供出來的,網上很多開源軟件也是有用到大量的自己量身定製的DLL 文件
****************************************************************************************************
VC 實現建立LIB 靜態鏈接庫的過程
做lib 庫文件在windows 彙編是一個重要主題
就談一下在VC 裏面如何實現用C 做一個靜態文件庫*.lib
然後用程序去調用lib 庫裏的函數的例子
****************************************************************************************************
1. 用VC 建立一個lib.h 文件
///lib.h file
#ifndef LIB_H
#define LIB_H
extern "C" int add(int x,int y);
extern "C" int sub(int x,int y);
extern "C" int mul(int x,int y);
extern "C" int div(int x,int y);
extern "C" int mod(int x,int y);
#endif
2. 用VC 建立一個lib.cpp 文件
// lib.cpp
#include "lib.h"
int add(int x,int y){return x + y;}
int sub(int x,int y){return x - y;}
int mul(int x,int y){return x * y;}
int div(int x,int y){return x / y;}
int mod(int x,int y){return x % y;}
3. 用VC 新建立一個工作區,再新建立一個工程文件lib,
工程類型選擇win32 static library ,下一步爲空工程,
在工程中把上面的lib.h,lib.cpp 添加到工程中,編譯後
系統就會生在一個lib.lib 的靜態鏈接庫文件,到止爲止已經建立OK
4. 調用一個靜態鏈接庫文件列子
// main.cpp : use this lib.lib
#include <stdio.h>
#include "lib.h" // 讓程序知道庫中的函數原型
#pragma comment(lib,"lib.lib") // 把這函數的實現庫lib.lib 導入代碼中,編譯器就會自動加載
int main(int argc, char* argv[]){
printf("13 + 6 = %d /n",add(3,6));
printf("12 - 5 = %d /n",sub(12,5));
printf("13 * 6 = %d /n",mul(3,6));
printf("15 / 5 = %d /n",div(15,5));
printf("12 %% 5 = %d /n",mod(12,5));
return 0;
}
運行結果爲是
13 + 6 = 18
12 - 5 = 7
13 * 6 = 78
15 / 5 = 3
12 % 5 = 2
****************************************************************************************************
VC 實現DLL(Win32 Dynamic-link library) 庫的過程
它是WIN32 下的DLL ,而不是MFC 的DLL
只要在頭文件指出聲明那些函數將會支持被導出
關鍵字是:__declspec(dllexport) ,常用於直接加在函數前面
如:extern "C" int __declspec(dllexport)add(int x, int y);
****************************************************************************************************
1. 建立頭文件
// 1.demodll.h
#ifndef LIB_H
#define LIB_H
extern "C" int __declspec(dllexport)add(int x,int y);
extern "C" int __declspec(dllexport)sub(int x,int y);
extern "C" int __declspec(dllexport)mul(int x,int y);
extern "C" int __declspec(dllexport)div(int x,int y);
extern "C" int __declspec(dllexport)mod(int x,int y);
#endif
2. 建立實現文件
//demodll.cpp
#include "demodll.h"
int add(int x,int y)
{ return x + y;}
int sub(int x,int y)
{ return x - y;}
int mul(int x,int y)
{ return x * y;}
int div(int x,int y)
{ return x / y;}
int mod(int x,int y)
{ return x % y;}
3. 用VC 新建立一個工作區,再新建立一個工程文件demodll,
工程類型選擇win32 dynamic-link library ,下一步爲空工程,
在工程中把上面的demodll.h,demodll.cpp 添加到工程中,編譯後
系統就會生在一個demodll.DLL 的靜態鏈接庫文件,到止爲止已經建立OK
4. 調用DLL 中的函數功能的例子
建立一個全新的win32 application 應用程序,
userdll.cpp 代碼如下
#include <stdio.h>
#include <windows.h>
typedef int(*lpAddFun)(int, int); // 宏定義函數指標類型
int main(int argc, char *argv[])
{
HINSTANCE hDll; //DLL 控制碼
lpAddFun addFun; // 函數指針
hDll = LoadLibrary("demodll.dll");
if (hDll != NULL)
{
addFun = (lpAddFun)GetProcAddress(hDll, "add");
if (addFun != NULL)
{
int result = addFun(3,15);
printf("addFun(3,15)=%d/n", result);
}
FreeLibrary(hDll);
}
return 0;
}
運行結果是addFun(3,15)=18 ,結果OK
轉自點擊打開鏈接