copy大神:
静态调用动态链接库DLL
调用DLL有两种方式,一种是静态调用,另一种就是动态调用。静态调用需要LIB库文件和DLL文件,程序编译时,需要用到LIB文件,发布时这个LIB文件就不再需要,而且,编译系统时,这个动态链接库已编译进程序,这样,在程序一开始运行时就会查找这个DLL文件,如果这个DLL文件不存在,那么,程序是启动不起来的。相反,动态调用DLL则不是这样,它只需要DLL文件,程序运行时,程序不需要知道这个DLL文件当前是否存在,只有当程序运行到某个点,才需要去调用DLL文件多个应用程序调用DLL时,DLL 在内存中只产生一个实例,因此,可以有效地节省内存空间,提高系统的运行效率。注意到,DLL 的编制与编程语言无关,只要遵守DLL的接口规范,许多语言都可以开发出高效的DLL程序,其它语言开发的DLL,同样可以在BCB中调用。
下面介绍以myDLL.dll为例静态调用DLL的步骤:
1、将myDLL.dll和myDLL.lib文件拷入到开发工程中,注意到,应用程序发布时,这个lib文件是不需要的。如果是其它语言开发的DLL,在没有lib文件的情况下,可以用implib.exe工具程序,生成一个lib文件,用法:
implib.exe 文件名.lib 文件名.DLL
2、Project-Add to project将myDLL.lib库导入到工程。
如果要从工程中清除库文件,方法有两种:
a、Project-Remove from project
b、View-Project Manager
3、在工程的Unit1.cpp中写程序代码:
---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
extern "C" __declspec(dllimport) __stdcall int myAdd(int,int);
extern "C" __declspec(dllimport) __stdcall AnsiString aboutMe(void);
---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int n;
n=myAdd(1,2);
ShowMessage(IntToStr(n));
}
---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
ShowMessage(aboutMe());
}
---------------------------------------------------------------------------
三 动态调用动态链接库DLL
动态调用DLL函数可分为八步:
第一步:函数定义。这里的函数为地址转换函数。下面这个函数其实就是定义 int __stdcall myAdd(int,int);
int __stdcall (*myAdd)(int,int);
第二步:定义模块句柄,全局变量,它是载入DLL文件后的实例
HINSTANCE HmyDLL;
第三步:装入DLL文件,同时获得它的句柄
HmyDLL=LoadLibrary("myDLL.dll");
第四步:定义函数地址变量
FARPROC P;
第五步:获取动态链接库内的某一函数的内存地址
P=GetProcAddress(HmyDLL,"myAdd");
第六步:强制类型转换,即将所获取的函数地址强制转换为函数
myAdd=(int __stdcall (__cdecl *)(int,int))P;
第七步:函数调用
n=myAdd(10,20);
第八步:释放DLL
FreeLibrary(HmyDLL);
下面以动态调用myDLL.dll函数为例,进行讲解:
---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
第一步:函数定义。这里的函数为地址转换函数。下面这个函数其实就是定义 int __stdcall myAdd(int,int);
int __stdcall (*myAdd)(int,int);
AnsiString __stdcall (*aboutMe)(void);
第二步:定义模块句柄,全局变量,它是载入DLL文件后的实例
HINSTANCE HmyDLL;
---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
第三步:装入DLL文件,同时获得它的句柄
HmyDLL=LoadLibrary("myDLL.dll");
}
---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int n;
第四步:定义函数地址变量
FARPROC P;
if(HmyDLL!=NULL)
{
第五步:获取动态链接库内的某一函数的内存地址
P=GetProcAddress(HmyDLL,"myAdd");
if(P==NULL)
{
ShowMessage("打开myAdd()函数错误!");
}
else
{
第六步:强制类型转换,即将所获取的函数地址强制转换为函数
myAdd=(int __stdcall (__cdecl *)(int,int))P;
第七步:函数调用
n=myAdd(10,20);
ShowMessage(IntToStr(n));
静态调用动态链接库DLL
调用DLL有两种方式,一种是静态调用,另一种就是动态调用。静态调用需要LIB库文件和DLL文件,程序编译时,需要用到LIB文件,发布时这个LIB文件就不再需要,而且,编译系统时,这个动态链接库已编译进程序,这样,在程序一开始运行时就会查找这个DLL文件,如果这个DLL文件不存在,那么,程序是启动不起来的。相反,动态调用DLL则不是这样,它只需要DLL文件,程序运行时,程序不需要知道这个DLL文件当前是否存在,只有当程序运行到某个点,才需要去调用DLL文件多个应用程序调用DLL时,DLL 在内存中只产生一个实例,因此,可以有效地节省内存空间,提高系统的运行效率。注意到,DLL 的编制与编程语言无关,只要遵守DLL的接口规范,许多语言都可以开发出高效的DLL程序,其它语言开发的DLL,同样可以在BCB中调用。
下面介绍以myDLL.dll为例静态调用DLL的步骤:
1、将myDLL.dll和myDLL.lib文件拷入到开发工程中,注意到,应用程序发布时,这个lib文件是不需要的。如果是其它语言开发的DLL,在没有lib文件的情况下,可以用implib.exe工具程序,生成一个lib文件,用法:
implib.exe 文件名.lib 文件名.DLL
2、Project-Add to project将myDLL.lib库导入到工程。
如果要从工程中清除库文件,方法有两种:
a、Project-Remove from project
b、View-Project Manager
3、在工程的Unit1.cpp中写程序代码:
---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
extern "C" __declspec(dllimport) __stdcall int myAdd(int,int);
extern "C" __declspec(dllimport) __stdcall AnsiString aboutMe(void);
---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int n;
n=myAdd(1,2);
ShowMessage(IntToStr(n));
}
---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
ShowMessage(aboutMe());
}
---------------------------------------------------------------------------
三 动态调用动态链接库DLL
动态调用DLL函数可分为八步:
第一步:函数定义。这里的函数为地址转换函数。下面这个函数其实就是定义 int __stdcall myAdd(int,int);
int __stdcall (*myAdd)(int,int);
第二步:定义模块句柄,全局变量,它是载入DLL文件后的实例
HINSTANCE HmyDLL;
第三步:装入DLL文件,同时获得它的句柄
HmyDLL=LoadLibrary("myDLL.dll");
第四步:定义函数地址变量
FARPROC P;
第五步:获取动态链接库内的某一函数的内存地址
P=GetProcAddress(HmyDLL,"myAdd");
第六步:强制类型转换,即将所获取的函数地址强制转换为函数
myAdd=(int __stdcall (__cdecl *)(int,int))P;
第七步:函数调用
n=myAdd(10,20);
第八步:释放DLL
FreeLibrary(HmyDLL);
下面以动态调用myDLL.dll函数为例,进行讲解:
---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
第一步:函数定义。这里的函数为地址转换函数。下面这个函数其实就是定义 int __stdcall myAdd(int,int);
int __stdcall (*myAdd)(int,int);
AnsiString __stdcall (*aboutMe)(void);
第二步:定义模块句柄,全局变量,它是载入DLL文件后的实例
HINSTANCE HmyDLL;
---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
第三步:装入DLL文件,同时获得它的句柄
HmyDLL=LoadLibrary("myDLL.dll");
}
---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int n;
第四步:定义函数地址变量
FARPROC P;
if(HmyDLL!=NULL)
{
第五步:获取动态链接库内的某一函数的内存地址
P=GetProcAddress(HmyDLL,"myAdd");
if(P==NULL)
{
ShowMessage("打开myAdd()函数错误!");
}
else
{
第六步:强制类型转换,即将所获取的函数地址强制转换为函数
myAdd=(int __stdcall (__cdecl *)(int,int))P;
第七步:函数调用
n=myAdd(10,20);
ShowMessage(IntToStr(n));