C++Builder建立及调用DLL
2016-11-28 15:37
92 查看
C++Builder建立及调用DLL
DLL简称动态链接库,是Windows中程序的重要组成部分。想象一下,一个程序需要多人共同完成开发,怎么个共同法?这时我们就要考虑把程
序分为好几个模块,团队每一个成员开发一个模块。问题来了:如何将模块组合并成一个完整系统?还有,我们开发的软件需要不断升级,如
何升级?难道每次非得把整个工程重新编译一次再发布给用户吗?解决这些问题的科学办法,就是开发动态链接库DLL。
现在以开发myDLL.dll动态链接库为例,讲讲BCB中开发动态链接库的方法。
1、新建立一个工程:File-New-Other...在New卡中选择DLL Wizard
2、将工程存为myDLL.bpr
3、在myDLL.cpp中写接口代码:
////---------------------------------------------------------------------------
#include<vcl.h>
#include <windows.h>
#pragma hdrstop
////---------------------------------------------------------------------------
//// Important note about DLL memory management when your DLL usesthe
//// static version of the RunTime Library:
////
//// If your DLL exports any functions that pass String objects (orstructs/
//// classes containing nested Strings) as parameter or functionresults,
//// you will need to add the library MEMMGR.LIB to both the DLLproject and
//// any other projects that use the DLL. You will also need to useMEMMGR.LIB
//// if any other projects which use the DLL will be performing newor delete
//// operations on any non-TObject-derived classes which areexported from the
//// DLL. Adding MEMMGR.LIB to your project will change the DLL andits calling
//// EXE's to use the BORLNDMM.DLL as their memory manager. Inthese cases,
//// the file BORLNDMM.DLL should be deployed along with your DLL.
////
//// To avoid using BORLNDMM.DLL, pass string information using"char *" or
//// ShortString parameters.
////
//// If your DLL uses the dynamic version of the RTL, you do notneed to
//// explicitly add MEMMGR.LIB as this will be done implicitly foryou
////---------------------------------------------------------------------------
extern "C" __declspec(dllexport) __stdcall int myAdd(int,int);
extern "C" __declspec(dllexport) __stdcall AnsiString aboutMe(void);
int add(int n1,int n2);
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*lpReserved)
{
return 1;
}
////---------------------------------------------------------------------------
__declspec(dllexport) __stdcall int myAdd(int n1,int n2)
{
int T;
T=add(n1,n2);
return T;
}
int add(int n1,int n2)
{
return n1+n2;
}
__declspec(dllexport) __stdcall AnsiString aboutMe(void)
{
return "曾棕根好你个大笨蛋,居然现在才学会用DLL!半年前施勇强就告诉了你呀!研究进度太慢!";
}
4、需要注意的是,在编写DLL这样的程序时,要力求简单,少用大量内存分配,尽量按照标准C的程序设计方法,以模块化结构设计为好,少采
用面向对象的程序设计方法。
5、进入Project-Options:
勾掉Linker页中的Use Dynamic RTL
勾掉Packages页中的Build with runtime packages
按一次Compiler中的Release按钮
在Version Info页中勾选Include version information in project,并勾选Auto-incrementbuild number,再在里面设置好版权信息
6、现在可以进入Project-Build myDLL生成myDLL.dll和myDLL.lib这两个文件。
二 静态调用动态链接库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 __stdcallmyAdd(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 __stdcallmyAdd(int,int);
int __stdcall (*
941b
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));
}
}
else
{
ShowMessage("打开动态链接库文件myDLL.dll错误!");
}
}
////---------------------------------------------------------------------------
void__fastcall TForm1::FormDestroy(TObject *Sender)
{
////第八步:释放DLL
FreeLibrary(HmyDLL);
}
////---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
FARPROC P;
if(HmyDLL!=NULL)
{
P=GetProcAddress(HmyDLL,"aboutMe");
if(P==NULL)
{
ShowMessage("打开aboutMe()函数错误!");
}
else
{
aboutMe=(AnsiString __stdcall (__cdecl*)(void))P;
ShowMessage(aboutMe());
}
}
else
{
ShowMessage("打开动态链接库文件myDLL.dll错误!");
}
}
////---------------------------------------------------------------------------
注意:动态调入myDLL.dll文件后,它在内存中只存在一个副本,这时,动态链接库文件已于关闭状态。
转自:http://blog.csdn.net/ww425/archive/2005/03/01/306500.aspx 转发请注明!!!!!
DLL简称动态链接库,是Windows中程序的重要组成部分。想象一下,一个程序需要多人共同完成开发,怎么个共同法?这时我们就要考虑把程
序分为好几个模块,团队每一个成员开发一个模块。问题来了:如何将模块组合并成一个完整系统?还有,我们开发的软件需要不断升级,如
何升级?难道每次非得把整个工程重新编译一次再发布给用户吗?解决这些问题的科学办法,就是开发动态链接库DLL。
现在以开发myDLL.dll动态链接库为例,讲讲BCB中开发动态链接库的方法。
1、新建立一个工程:File-New-Other...在New卡中选择DLL Wizard
2、将工程存为myDLL.bpr
3、在myDLL.cpp中写接口代码:
////---------------------------------------------------------------------------
#include<vcl.h>
#include <windows.h>
#pragma hdrstop
////---------------------------------------------------------------------------
//// Important note about DLL memory management when your DLL usesthe
//// static version of the RunTime Library:
////
//// If your DLL exports any functions that pass String objects (orstructs/
//// classes containing nested Strings) as parameter or functionresults,
//// you will need to add the library MEMMGR.LIB to both the DLLproject and
//// any other projects that use the DLL. You will also need to useMEMMGR.LIB
//// if any other projects which use the DLL will be performing newor delete
//// operations on any non-TObject-derived classes which areexported from the
//// DLL. Adding MEMMGR.LIB to your project will change the DLL andits calling
//// EXE's to use the BORLNDMM.DLL as their memory manager. Inthese cases,
//// the file BORLNDMM.DLL should be deployed along with your DLL.
////
//// To avoid using BORLNDMM.DLL, pass string information using"char *" or
//// ShortString parameters.
////
//// If your DLL uses the dynamic version of the RTL, you do notneed to
//// explicitly add MEMMGR.LIB as this will be done implicitly foryou
////---------------------------------------------------------------------------
extern "C" __declspec(dllexport) __stdcall int myAdd(int,int);
extern "C" __declspec(dllexport) __stdcall AnsiString aboutMe(void);
int add(int n1,int n2);
#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*lpReserved)
{
return 1;
}
////---------------------------------------------------------------------------
__declspec(dllexport) __stdcall int myAdd(int n1,int n2)
{
int T;
T=add(n1,n2);
return T;
}
int add(int n1,int n2)
{
return n1+n2;
}
__declspec(dllexport) __stdcall AnsiString aboutMe(void)
{
return "曾棕根好你个大笨蛋,居然现在才学会用DLL!半年前施勇强就告诉了你呀!研究进度太慢!";
}
4、需要注意的是,在编写DLL这样的程序时,要力求简单,少用大量内存分配,尽量按照标准C的程序设计方法,以模块化结构设计为好,少采
用面向对象的程序设计方法。
5、进入Project-Options:
勾掉Linker页中的Use Dynamic RTL
勾掉Packages页中的Build with runtime packages
按一次Compiler中的Release按钮
在Version Info页中勾选Include version information in project,并勾选Auto-incrementbuild number,再在里面设置好版权信息
6、现在可以进入Project-Build myDLL生成myDLL.dll和myDLL.lib这两个文件。
二 静态调用动态链接库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 __stdcallmyAdd(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 __stdcallmyAdd(int,int);
int __stdcall (*
941b
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));
}
}
else
{
ShowMessage("打开动态链接库文件myDLL.dll错误!");
}
}
////---------------------------------------------------------------------------
void__fastcall TForm1::FormDestroy(TObject *Sender)
{
////第八步:释放DLL
FreeLibrary(HmyDLL);
}
////---------------------------------------------------------------------------
void __fastcall TForm1::Button2Click(TObject *Sender)
{
FARPROC P;
if(HmyDLL!=NULL)
{
P=GetProcAddress(HmyDLL,"aboutMe");
if(P==NULL)
{
ShowMessage("打开aboutMe()函数错误!");
}
else
{
aboutMe=(AnsiString __stdcall (__cdecl*)(void))P;
ShowMessage(aboutMe());
}
}
else
{
ShowMessage("打开动态链接库文件myDLL.dll错误!");
}
}
////---------------------------------------------------------------------------
注意:动态调入myDLL.dll文件后,它在内存中只存在一个副本,这时,动态链接库文件已于关闭状态。
转自:http://blog.csdn.net/ww425/archive/2005/03/01/306500.aspx 转发请注明!!!!!
相关文章推荐
- C++Builder调用VC生成的DLL方法
- c++builder ZIP文件解压与压缩(ZLIB DLL调用)(转载 )
- Visual Studio下建立并隐式调用自己的动态链接库dll
- C++Builder调用其他dll
- C++Builder及VC的DLL相互调用示例
- c语言建立和调用dll
- 在C#中调用C++Builder编写的DLL
- C++Builder、C#、VC调用 C++Builder制作的DLL
- c++建立DLL 及c# 调用
- C++Builder及VC的DLL相互调用
- Delphi中DLL的建立和调用
- 我在DLL中建立了一个TImage,但调用时出现错误"Cannot assign a TFont to a TFont"
- c++builder ZIP文件解压与压缩(ZLIB DLL调用),目录复制与删除整合的自用类,可自行扩张!
- BCB(C++Builder或Embarcadero XE)中调用托管DLL的方法(C++调用C#的DLL)
- Qt中隐式调用VS建立的dll动态库
- c++builder调用VC的dll以及VC调用c++builder的dll
- Visual Studio下建立并隐式调用自己的动态链接库dll
- Visual Studio下建立并隐式调用自己的动态链接库dll
- 在C++builder中用伪造的dll生成的lib文件可正常调用vc写的dll
- c++建立DLL 及c# 调用