首页 > 其他分享 >BCB中开发动态链接库的方法

BCB中开发动态链接库的方法

时间:2022-09-25 02:44:20浏览次数:54  
标签:__ int myDLL BCB DLL stdcall 开发 动态链接库 myAdd

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 (*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文件后,它在内存中只存在一个副本,这时,动态链接库文件已于关闭状态.

标签:__,int,myDLL,BCB,DLL,stdcall,开发,动态链接库,myAdd
From: https://www.cnblogs.com/icaowu/p/16727133.html

相关文章

  • Linux 服务器开发基础学习笔记
    Linux发展历史1969--unix肯汤姆森,C丹尼斯里奇商业:-IBM-APPLE-惠普-sunBSD:-freeBSDLinux:-redhatcentos-debainubuntuMMU作用......
  • c#用visual studio开发时输出信息到consolel.writeline控制台的方法
    winform程序进行Console.WriteLine(result)输出时是无的,但很多时候我们开发时希望输出一些信息来查看代码运行情况,我们可以这样操作:1.在解决方案资源管理器右击项目名-......
  • 每个开发人员都应该知道的基本 Git 命令
    每个开发人员都应该知道的基本Git命令Githubgit克隆用于将目录从GitHub复制到您的计算机。git克隆主要用于指向现有存储库,并在另一个位置的新目录中创建该存......
  • 使用 Python 3 开发聊天机器人
    使用Python3开发聊天机器人我最近登陆了一个小项目,使用Python3开发了一个在Telegram平台上使用的聊天机器人。您可以查看机器人帐户@https://t.me/AI_12_Bot.......
  • windows平台下sublime配置python开发环境
    目录1,下载与安装2,包管理的安装3,sublime软件环境配置3,编译&运行1,下载与安装1.下载(官网http://www.sublimetext.com/download)并安装即可。2,包管理的安装1.将安装后的b......
  • 【视觉小说游戏开发】bkengine教程-使用宏(高级篇)-宏的返回
    首先去下载bkengineBKEngine - AVG/Galgame游戏引擎 - 免费 易用 高效 安全 跨平台(bakery.moe)创建myreturn.bkscr并写入*register//这之间写上要定义的宏或......
  • 为什么开发人员不喜欢 CSS?
    为什么开发人员不喜欢CSS?PeterGriffin—AmericanDad对我来说,写我的第一篇关于这个流行短语的Web集成文章似乎很明显:“我不喜欢CSS”谁以前没有听过或说过这......
  • 工业软件为什么这么难开发?
    工业软件开发难是由其专业性强、复杂度高、个性化要求大等多方面因素导致的。下面从工业定义、应用场景等多个方面来做阐述。工业软件是对工业研发设计、生产制造、经营管......
  • 纯注解开发模式
    定义bean:   纯注解开发模式:用SpringConfig类来代替applicationContext.xml配置文件,利用注解@configuration代表了xml里的基本配置,在SpringConfig类中再加一个注解@......
  • Google开发者大会最全视频资源
    最全的视频资源在官网,但同时,leetcode整理的个人觉得更加的棒! 特别企划|力扣带你逛谷歌开发者大会  Google开发者大会更大力的断推跨平台技术这几年总有些跑偏的......