靜態(tài),動態(tài)鏈接庫的生成與應(yīng)用
推薦:Windows核心編程---動態(tài)鏈接庫(XX.dll)與靜態(tài)庫(XX.lib)
最近細(xì)讀了Windows核心編程的內(nèi)存管理與動態(tài)鏈接庫部分,雖然有些人對Windows未來說三道四,但不得不承認(rèn)微軟windows系統(tǒng)的強(qiáng)大功能,以及其深邃的架構(gòu)設(shè)計思想
一 靜態(tài)鏈接庫的生成與應(yīng)用
在VC++6.0中new一個名稱為libTest的staticlibrary工程,并新建lib.h和lib.cpp兩個文件,lib.h和lib.cpp的源代碼如下:
//文件:lib.h
#ifndef LIB_H
#define LIB_H
extern "C" int add(int x,int y); //聲明為C編譯、連接方式的外部函數(shù)
#endif
//文件:lib.cpp
#include "lib.h"
int add(int x,int y)
{
return x + y;
}
編譯這個工程就得到了一個.lib文件,這個文件就是一個函數(shù)庫,它提供了add的功能。將頭文件和.lib文件提交給用戶后,用戶就可以直接使用其中的add函數(shù)了。
應(yīng)用舉例:
//新建一個libCall的win32工程,把生成的靜態(tài)鏈接庫放入該目錄下面
//按平時一樣編寫代碼
#include <stdio.h>
#include"..libCalllib.h"
#pragma comment( lib,"..\libCall\libTest.lib" )
//指定與靜態(tài)庫一起連接
int main(int argc, char* argv[])
{
printf("2 + 3 = %d
", add( 2, 3 ) );
}
二 動態(tài)鏈接庫的生成與應(yīng)用
// dllTest.cpp : Defines the entry pointfor the DLL application.
//建立生成動態(tài)鏈接庫的工程dllTest
//編譯生成動態(tài)鏈接庫dllTest.dll,dllTest.lib
#include <stdio.h>
#pragma hdrstop
extern "C"_declspec(dllexport) int add(int x,int y);
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
int add(int x,int y)
{
returnx + y;
}
//動態(tài)鏈接庫的靜態(tài)調(diào)用
//建立dllLibCall工程,把上面生成的dllTest.dll,dllTest.lib拷貝到該工程目錄下
#include <stdio.h>
#pragma comment(lib,"..\dllLibCall\dllTest.lib")
extern "C" __declspec(dllimport)int __cdecl add(int x,int y);
int main()
{
printf("dllLibCall:2+ 3 = %d
",add(2,3));
return0;
}
運(yùn)行結(jié)果:dllLibCall:2 + 3 = 5
//動態(tài)鏈接庫的動態(tài)調(diào)用
//建立dllCall工程,把上面生成的dllTest.dll拷貝到該工程目錄下
#include <stdio.h>
#include <windows.h>
int main()
{
HINSTANCE hModule;
hModule = LoadLibrary("..\dllCall\dllTest.dll");
if(hModule)
{
typedef int (*LPFNREGISTER)(int x, int y);
LPFNREGISTER lpfnRegister;
lpfnRegister= (LPFNREGISTER)GetProcAddress(hModule,"add");
if(lpfnRegister)
{
printf("dllCall:2+ 3 = %d
",lpfnRegister(2, 3));
}
}
FreeLibrary(hModule);
return0;
}
運(yùn)行結(jié)果:dllCall:2 + 3 = 5 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 補(bǔ)充的相關(guān)知識點(diǎn): 動態(tài)鏈接庫(DLL)是Windows編程常遇到的編程方法,下面我就介紹一下在BCB (C++Builder下簡稱BCB) 中如何創(chuàng)建使用DLL和一些技巧。
一、創(chuàng)建:
使用BCB File|NEW建立一個新的DLL工程,并保存好文件BCB,生成一個DLL的程序框架。
1.DllEntryPoint函數(shù)為一個入口方法,如果使用者在DLL被系統(tǒng)初始化或者注銷時被調(diào)用,用來寫入對DLL的初始化程序和卸載程序;參數(shù):hinst用來指示DLL的基地址;reason用來指示DLL的調(diào)用方式,用于區(qū)別多線程單線程對DLL的調(diào)用、創(chuàng)建、卸載DLL;
2.在程序中加入自己所要創(chuàng)建的DLL過程、函數(shù);
3.用dllimport描述出口;
例程序如下:
?。nclude
#pragma hdrstop
extern “C” __declspec(dllexport) int test();
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*)
{
return 1;
}
int test()
{
return 3;
}
注意:動態(tài)鏈接庫中調(diào)用過程、函數(shù)時有不同的CALL方式 __cdecl、 __pascal, __fastcall、__stdcall,BCB中默認(rèn)的方式為__cdecl(可不寫),如果考慮兼容性可用時__stdcall聲明方法為:
extern “C” __declspec(dllexport) int __stdcall test();
對于其中過程、函數(shù)也改為:
int __stdcall test()
二、使用DLL
在BCB中使用DLL有兩種方法:
1.用靜態(tài)調(diào)用法
首先需要在BCB的項目中加入輸入接口庫(import library),打開工程項目,使用BCB View|Project Manager打開項目列表,向項目中加入接口庫(*.lib)。
其次在頭文件中加入接口聲明。
例程序如下:
//define in include file
extern “C” __declspec(dllimport) int __cdecl test();
//use function in main program
int I;
I=test();
注意:
(1)動態(tài)鏈接庫調(diào)用過程、函數(shù)時CALL方式 與創(chuàng)建時方式一樣不寫為__cdecl,其它需要聲明。
(2)BCB創(chuàng)建的DLL有對應(yīng)的輸入接口庫(import library),如只有DLL而無庫時,可用BCB的implib工具產(chǎn)生:implib xxx.lib xxx.dll;另外可用:tlib xxx.lib,xxx.lst 產(chǎn)生DLL的內(nèi)部函數(shù)列表,許多Windows的未公開技術(shù)就是用這種方法發(fā)現(xiàn)的。
2.動態(tài)調(diào)用法
動態(tài)調(diào)用法要用Windows API 中的LoadLibrary()和GetProcAddress()來調(diào)入DLL庫,指出庫中函數(shù)位置,這種方法較常見。
例程序如下:
HINSTANCE dd;
int _stdcall (*ddd)(void);
dd=LoadLibrary(“xxx.dll”);
ddd=GetProcAddress(dd,“test”);
Caption=IntToStr(ddd());
FreeLibrary(dd);
三、注意:
創(chuàng)建DLL時編譯鏈接時注意設(shè)置Project Options。
Packages標(biāo)簽:去除Builder with runtime packages檢查框。
Linker標(biāo)簽:去除Use dynamic RTL檢查框。
否則創(chuàng)建的DLL需要Runtime packages or Runtime library。
一 靜態(tài)鏈接庫的生成與應(yīng)用 在VC++6.0中new一個名稱為libTest的staticlibrary工程,并新建lib.h和lib.cpp兩個文件,lib.h和lib.cpp的源代碼如下: //文件:lib.h#ifndef LIB_H#define LIB_H