CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
【经验总结】不能实施并行处理的情况 浅谈并行编程中的任务分解模式
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  C++ Builder >  基础类

如何用c++ builder编译器生成dll文件?在线等待!

楼主leotonny(天马行空的生涯)2003-10-22 14:49:06 在 C++ Builder / 基础类 提问

我开发都用java,现在要调用dll,所以用到c++   builder编译器,但不知怎么生成dll文件?是用ilink32命令吗?现在只有一个测试文件Sample1.cpp,没有其他资源文件。  
  问题点数:50、回复次数:5Top

1 楼pzoon(杀死日本人)回复于 2003-10-22 15:01:33 得分 10

如果你需要在一个工程中包含*.lib的话可以通过菜单Project|Add   to   Project,然后文件类型选择“(*.lib)”,把你想要添加的*.lib文件加入到工程中就可以了。  
  静态调用需要有三种文件  
  1、所需要调用的DLL文件。2、此DLL的输入库文件。3、此DLL的对应头文件  
  静态调用时,在工程中先导入此DLL的输入库文件,然后在你的工程中include进此DLL的对应头文件,之后就像使用平常函数一样使用DLL的函数了。  
  动态调用:  
  首先需要调用LoadLibrary你的DLL文件,比如:  
  HINSTANCE   hInstance;  
  hInstance   =   LoadLibrary("DLL.dll");  
  然后调用GetProAddress,引入你的函数,比如:  
  FARPROC   WriteProc;  
  WriteProc   =   GetProcAddress(hInstance   ,   "WriteXMLFile");   如果你调用的函数有参数还需要进行必要的指针类型转化,比如:  
  WriteXMLFile函数有两个参数都是char*   的那么转换为  
  typedef   int(*   WriteFUNC)(char*   ,char   *);  
  WriteFUNC   WriteFile   =   (WriteFUNC)WriteProc;  
  然后用WriteFile来传递参数进行函数调用。  
  调用完毕别忘了调用FreeLibrary。  
  但是如果是导出类的话是不能用动态调用的,只能用静态调用。  
  Top

2 楼ccrun(老妖)(www.ccrun.com)回复于 2003-10-22 15:05:47 得分 20

作者:   Behard   阅读:1565   加入时间:2003-6-5   本文来自http://www.ccrun.com    
   
  --------------------------------------------------------------------------------  
      由于现在比较多的网友老是在   CSDN   上询问关于   BCB   编写   DLL   的问题,我编写了这篇文章抛砖引玉  
   
  一.   编写   DLL  
      File/New/Dll   生成   Dll   的向导,然后可以添加导出函数和导出类  
      导出函数:extern   "C"   __declspec(dllexport)   ExportType   FunctionName(Parameter)  
      导出类:class   __declspec(dllexport)   ExportType   ClassName{...}  
      例子:(说明:只是生成了一个   DLL.dll   )  
   
  #include   "DllForm.h"     //   TDllFrm   定义  
   
  USERES("Dll.res");  
  USEFORM("DllForm.cpp",   DllFrm);  
   
  class   __declspec(dllexport)   __stdcall   MyDllClass   {   //导出类  
          public:  
                MyDllClass();  
                void   CreateAForm();  
                TDllFrm*   DllMyForm;  
  };  
   
  TDllFrm*   DllMyForm2;  
  extern   "C"   __declspec(dllexport)   __stdcall   void   CreateFromFunct();//导出函数  
   
  //---------------------------------------------------------------------------  
  int   WINAPI   DllEntryPoint(HINSTANCE   hinst,   unsigned   long   reason,   void*)  
  {  
          return   1;  
  }  
  //---------------------------------------------------------------------------  
   
  MyDllClass::MyDllClass()  
  {  
  }  
   
  void   MyDllClass::CreateAForm()  
  {  
          DllMyForm   =   new   TDllFrm(Application);  
          DllMyForm->Show();  
  }  
  //---------------------------------------------------------------------------  
  void   __stdcall   CreateFromFunct()  
  {  
          DllMyForm2   =   new   TDllFrm(Application);  
          DllMyForm2->Show();  
  }  
   
   
  二.   静态调用   DLL  
  使用   $BCB   path\Bin\implib.exe   生成   Lib   文件,加入到工程文件中  
  将该文件拷贝到当前目录,使用   implib   MyDll.lib   MyDll.dll   生成  
  //   Unit1.h   //   TForm1   定义  
  #include   "DllForm.h"   //   TDllFrm   定义  
  //---------------------------------------------------------------------------  
   
  __declspec(dllimport)   class   __stdcall   MyDllClass   {  
          public:  
                  MyDllClass();  
                  void   CreateAForm();  
                  TDllFrm*   DllMyForm;  
  };    
  extern   "C"   __declspec(dllimport)   __stdcall   void   CreateFromFunct();  
   
  class   TForm1   :   public   TForm{...}  
   
   
  //   Unit1.cpp   //   TForm1   实现  
  void   __fastcall   TForm1::Button1Click(TObject   *Sender)  
  {   //   导出类实现,导出类只能使用静态方式调用  
          DllClass   =   new   MyDllClass();  
          DllClass->CreateAForm();          
  }  
  //---------------------------------------------------------------------------  
  void   __fastcall   TForm1::Button2Click(TObject   *Sender)  
  {   //   导出函数实现  
          CreateFromFunct();  
  }  
  //---------------------------------------------------------------------------  
   
  void   __fastcall   TForm1::FormClose(TObject   *Sender,   TCloseAction   &Action)  
  {  
          delete   DllClass;  
  }  
   
  三.   动态调用   DLL  
  //   Unit1.h    
  class   TForm1   :   public   TForm  
  {  
  ...  
  private:   //   User   declarations  
  void   (__stdcall   *CreateFromFunct)();  
  ...  
  }  
   
  //   Unit1.cpp   //   TForm1  
  HINSTANCE   DLLInst   =   NULL;  
  void   __fastcall   TForm1::Button2Click(TObject   *Sender)  
  {  
          if(   NULL   ==   DLLInst   )   DLLInst   =   LoadLibrary("DLL.dll");   //上面的   Dll  
          if   (DLLInst)   {    
                  CreateFromFunct   =   (void   (__stdcall*)())   GetProcAddress(DLLInst,  
                                                                                                          "CreateFromFunct");  
                  if   (CreateFromFunct)   CreateFromFunct();  
                  else   ShowMessage("Could   not   obtain   function   pointer");  
          }  
          else   ShowMessage("Could   not   load   DLL.dll");  
  }  
   
  void   __fastcall   TForm1::FormClose(TObject   *Sender,   TCloseAction   &Action)  
  {  
          if   (   DLLInst   )   FreeLibrary   (DLLInst);  
  }  
       
  四.   DLL   作为   MDIChild   (子窗体)   【只编写动态调用的例子】  
          实际上,调用子窗体的   DLL   时,系统只是检查应用程序的   MainForm   是否为   fsMDIForm   的窗体,这样只  
   
  要把调用程序的   Application   的   Handle   传递给   DLL   的   Application   即可;同时退出   DLL   时也要恢复    
   
  Application  
   
  //   MDIChildPro.cpp   //   Dll   实现   CPP  
  #include   "unit1.h"   //   TForm1   定义  
  TApplication   *SaveApp   =   NULL;  
  int   WINAPI   DllEntryPoint(HINSTANCE   hinst,   unsigned   long   reason,   void*)  
  {  
          if   (   (reason==DLL_PROCESS_DETACH)   &&   SaveApp   )  
                  Application   =   SaveApp   ;   //   恢复   Application  
          return   1;  
  }  
   
  extern   "C"   __declspec(dllexport)   __stdcall   void   TestMDIChild(         //1024X768  
          TApplication*   mainApp,  
          LPSTR   lpCaption)  
  {  
          if   (   NULL   ==   SaveApp   )   //   保存   Application,传递   Application  
          {  
                  SaveApp   =   Application;  
                  Application   =   mainApp;  
          }  
          //   lpCaption   为子窗体的   Caption  
          TForm1   *Form1   =   new   TForm1   (   Application,   lpCaption   );    
          Form1->Show();  
  }  
  注:上面的程序使用   BCB   3.0   编译成功  
   
  五.   BCB   调用   VC   编写的   DLL  
      1.   名字分解:  
          没有名字分解的函数  
                  TestFunction1   //   __cdecl   calling   convention  
                  @TestFunction2   //   __fastcall   calling   convention  
                  TESTFUNCTION3   //   __pascal   calling   convention  
                  TestFunction4   //   __stdcall   calling   convention  
          有名字分解的函数  
                  @TestFunction1$QV   //   __cdecl   calling   convention  
                  @TestFunction2$qv   //   __fastcall   calling   convention  
                  TESTFUNCTION3$qqrv   //   __apscal   calling   convention  
                  @TestFunction4$qqrv   //   __stdcall   calling   convention  
          使用   extern   "C"   不会分解函数名  
   
          使用   Impdef   MyLib.def   MyLib.DLL   生成   def   文件查看是否使用了名字分解  
   
      2.   调用约定:  
          __cdecl   缺省  
              是   Borland   C++   的缺省的   C   格式命名约定,它在标识符前加一下划线,以保留  
          它原来所有的全程标识符。参数按最右边参数优先的原则传递给栈,然后清栈。  
                  extaern   "C"   bool   __cdecl   TestFunction();  
              在   def   文件中显示为    
                  TestFunction   @1  
              注释:   @1   表示函数的顺序数,将在“使用别名”时使用。  
   
          __pascal   Pascal格式  
              这时函数名全部变成大写,第一个参数先压栈,然后清栈。  
                  TESTFUNCTION   @1   //def   file  
   
          __stdcall   标准调用  
              最后一个参数先压栈,然后清栈。  
                  TestFunction   @1   //def   file  
   
          __fastcall   把参数传递给寄存器  
              第一个参数先压栈,然后清栈。  
                  @TestFunction   @1   //def   file    
  Top

3 楼ccrun(老妖)(www.ccrun.com)回复于 2003-10-22 15:06:00 得分 20

3.   解决调用约定:  
              Microsoft   与   Borland   的   __stdcall   之间的区别是命名方式。   Borland   采用  
          __stdcall   的方式去掉了名字起前的下划线。   Microsoft   则是在前加上下划线,在  
          后加上   @   ,再后跟为栈保留的字节数。字节数取决于参数在栈所占的空间。每一个  
          参数都舍入为   4   的倍数加起来。这种   Miocrosoft   的   DLL   与系统的   DLL   不一样。  
   
      4.   使用别名:  
              使用别名的目的是使调用文件   .OBJ   与   DLL   的   .DEF   文件相匹配。如果还没有  
          .DEF   文件,就应该先建一个。然后把   DEF   文件加入   Project。使用别名应不断  
          修改外部错误,如果没有,还需要将   IMPORTS   部分加入   DEF   文件。  
                  IMPORTS  
                  TESTFUNCTIOM4   =   DLLprj.TestFunction4  
                  TESTFUNCTIOM5   =   DLLprj.WEP   @500  
                  TESTFUNCTIOM6   =   DLLprj.GETHOSTBYADDR   @51  
              这里需要说明的是,调用应用程序的   .OBJ   名与   DLL   的   .DEF   文件名是等价的,  
          而且总是这样。甚至不用考虑调用约定,它会自动匹配。在前面的例子中,函数被  
          说明为   __pascal,因此产生了大写函数名。这样链接程序不会出错。  
   
      5.   动态调用例子  
  VC   DLL   的代码如下:  
  extern   "C"   __declspec(dllexport)   LPSTR   __stdcall   BCBLoadVCWin32Stdcall()  
  {  
  static   char   strRetStdcall[256]   =   "BCB   Load   VC_Win32   Dll   by   __stdcall   mode   is   OK!";  
   
  return   strRetStdcall;  
  }    
   
  extern   "C"   __declspec(dllexport)   LPSTR   __cdecl   BCBLoadVCWin32Cdecl()  
  {  
  static   char   strRetCdecl[256]   =   "BCB   Load   VC_Win32   Dll   by   __cdecl   mode   is   OK!";  
   
  return   strRetCdecl;  
  }    
   
  extern   "C"   __declspec(dllexport)   LPSTR   __fastcall   BCBLoadVCWin32Fastcall()  
  {  
  static   char   strRetFastcall[256]   =   "BCB   Load   VC_Win32   Dll   by   __fastcall   mode   is   OK!";  
   
  return   strRetFastcall;  
  }    
   
            其实动态调用与调用   BCB   编写的   DLL   没有区别,关键是查看   DLL   的导出函数名字  
            可以使用   tdump.exe(BCB工具)   或者   dumpbin.exe(VC工具)   查看  
            tdump   -ee   MyDll.dll   >1.txt   (查看   1.txt   文件即可)  
            由于   VC6   不支持   __pascall   方式,下面给出一个三种方式的例子  
  void   __fastcall   TForm1::btnBLVCWin32DynClick(TObject   *Sender)  
  {  
          /*cmd:   tdbump   VCWin32.dll   >1.txt  
  Turbo   Dump     Version   5.0.16.4   Copyright   (c)   1988,   1998   Borland   International  
                                          Display   of   File   VCWIN32.DLL  
   
  EXPORT   ord:0000='BCBLoadVCWin32Fastcall::'  
  EXPORT   ord:0001='BCBLoadVCWin32Cdecl'  
  EXPORT   ord:0002='_BCBLoadVCWin32Stdcall@0'  
          */  
          if   (   !DllInst   )  
                  DllInst   =   LoadLibrary   (   "VCWin32.dll"   );  
          if   (   DllInst   )  
          {  
                  BCBLoadVCWin32Stdcall   =   (LPSTR   (__stdcall   *)   ()   )  
                          GetProcAddress   (   DllInst,   "_BCBLoadVCWin32Stdcall@0"   );   //VC   Dll  
                          //   GetProcAddress   (   DllInst,   "BCBLoadVCWin32Stdcall"   );   //BCB   Dll  
                  if   (   BCBLoadVCWin32Stdcall   )  
                  {  
                          ShowMessage(   BCBLoadVCWin32Stdcall()   );  
                  }  
                  else   ShowMessage   (   "Can't   find   the   __stdcall   Function!"   );  
   
                  BCBLoadVCWin32Cdecl   =   (LPSTR   (__cdecl   *)   ()   )  
                          GetProcAddress   (   DllInst,   "BCBLoadVCWin32Cdecl"   );  
                  if   (   BCBLoadVCWin32Cdecl   )  
                  {  
                          ShowMessage(   BCBLoadVCWin32Cdecl()   );  
                  }  
                  else   ShowMessage   (   "Can't   find   the   __cdecl   Function!"   );  
   
                  //Why?不是   'BCBLoadVCWin32Fastcall::',而是   '@BCBLoadVCWin32Fastcall@0'?  
                  BCBLoadVCWin32Fastcall   =   (LPSTR   (__fastcall   *)   ()   )  
                          //GetProcAddress   (   DllInst,   "BCBLoadVCWin32Fastcall::"   );  
                          GetProcAddress   (   DllInst,   "@BCBLoadVCWin32Fastcall@0"   );  
                  if   (   BCBLoadVCWin32Fastcall   )  
                  {  
                          ShowMessage(   BCBLoadVCWin32Fastcall()   );  
                  }  
                  else   ShowMessage   (   "Can't   find   the   __fastcall   Function!"   );  
          }  
          else   ShowMessage   (   "Can't   find   the   Dll!"   );  
  }  
   
      6.   静态调用例子  
            静态调用有点麻烦,从动态调用中可以知道导出函数的名字,但是直接时(加入   lib   文件到工程文件)    
   
  Linker   提示不能找到函数的实现  
            从   4   看出,可以加入   def   文件连接  
            (可以通过   impdef   MyDll.def   MyDll.dll   获得导出表)  
            建立与   DLL   文件名一样的   def   文件与   lib   文件一起加入到工程文件  
            上面的   DLL(VCWIN32.dll)   的   def   文件为(VCWIN32.def):  
  LIBRARY           VCWIN32.DLL  
   
  IMPORTS  
          @BCBLoadVCWin32Fastcall           =   VCWIN32.@BCBLoadVCWin32Fastcall@0  
          _BCBLoadVCWin32Cdecl                 =   VCWIN32.BCBLoadVCWin32Cdecl  
          BCBLoadVCWin32Stdcall               =   VCWIN32._BCBLoadVCWin32Stdcall@0  
   
  对应的函数声明和实现如下:  
  extern   "C"   __declspec(dllimport)   LPSTR   __fastcall   BCBLoadVCWin32Fastcall();  
  extern   "C"   __declspec(dllimport)   LPSTR   __cdecl   BCBLoadVCWin32Cdecl();  
  extern   "C"   __declspec(dllimport)   LPSTR   __stdcall   BCBLoadVCWin32Stdcall();  
   
  void   __fastcall   TfrmStatic::btnLoadDllClick(TObject   *Sender)  
  {  
          ShowMessage   (   BCBLoadVCWin32Fastcall()   );  
          ShowMessage   (   BCBLoadVCWin32Cdecl()   );  
          ShowMessage   (   BCBLoadVCWin32Stdcall()   );  
  }  
  Top

4 楼leotonny(天马行空的生涯)回复于 2003-10-22 15:07:16 得分 0

我没有安装c++   builder,只是下载了编译器,是在命令行下操作的,只有一个cpp文件,怎么把它编译成dll文件?vc++里有cl命令,c++   builder呢?Top

5 楼leotonny(天马行空的生涯)回复于 2003-10-24 12:48:27 得分 0

算了!!没人回答俺,散分!真郁闷!  
  我换成用vc++的cl做了,唉,csdn到底咋回事,怎么都是一些贴手,高手都md跑哪里去了?  
  都学得那么深藏不露干吗?Top

相关问题

  • Linux下的 C++ Builder 编译器
  • c++builder的编译器好用吗???
  • c编译器
  • C#的编译器
  • C的编译器
  • dev-c++编译器
  • 求c#编译器
  • C++ Builder 5中是否支持Corba,有IDL编译器吗?
  • 哪有C++编译器
  • 关于C++编译器。

关键词

  • c++ builder
  • vc++
  • win32
  • 函数
  • 文件
  • 编译器
  • bcb
  • dll
  • bcbloadvcwin32
  • 调用

得分解答快速导航

  • 帖主:leotonny
  • pzoon
  • ccrun
  • ccrun

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
惹火投票。。火热进行中...
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
CSDN网站24小时值班电话:13552009689
Copyright © 2000-2009, CSDN.NET, All Rights Reserved
GongshangLogo