创建DLL动态连接库

来源:互联网 发布:淘宝批量发布宝贝 编辑:程序博客网 时间:2024/06/10 01:31
创建DLL动态连接库
作者:不详  来源于:delphibbs.com  发布时间:2005-12-25 17:08:00  Windows 的执行文件可以划分为两种形式程序和动态连接库(DLLs)。一般程序运行是用.EXE文件,但应用程序有时也可以调用存储在DLL 中的函数。
    当我们调用Windows 中的API 函数的时候,实际上就是调用存储在DLL 中的函数。
    在如下几种情况下,调用DLL 是合理的:
    1) 不同的程序使用相同的DLL ,这样只需要将DLL 在内存中装载一次,节省了内存的开销。
    2) 当某些内容需要升级的时候,如果使用DLL 只需要改变DLL 就可以了,而不需要把整个程序都进行变动。
    3) 由于DLL 是独立于语言的,所以,当不同语言习惯的人共同开发一个大型项目的时候,使用DLL 便于程序系统的交流,当然,Delphi开发的DLL 也可以在诸如Visual BASIC,C++ 等系
统中使用。
    下面通过几个例子,说明Delphi开发动态连接库的方法和规范。    

    第一节 动态连接库的构建和调用方法
    一、动态连接库构建

    File---New---Other---DLL Wizard

    这就创建了一个动态连接库的基本模块

    library Project2;

    uses
      SysUtils,
      Classes;

   {$R *.res}

    begin

    end.

    把工程名改为Mydll,并写入必要的函数

    library mydll;

    uses
      SysUtils,Classes,Dialogs,windows;

    function Triple(N:Integer):integer;stdcall;
    begin
      result:=N+3;
    end;

    function Double(N:Integer):integer;stdcall;
    begin
      result:=N+2;
    end;

    function Triple1(N:Integer):integer;stdcall;
    begin
      showmessage('计算N+3');
      result:=N+3;
    end;

    function Double1(N:Integer):integer;stdcall;
    begin
      messagebox(0,'计算N+2','计算N+2',mb_ok);
      result:=N+2;
    end;

   exports
     Triple name 'Tr',
     Double name 'Do',
     Triple1 name 'TrM',
     Double1 name 'DoM';

    Triple,Double,Triple1,Double1;

  {$R *.RES}

  begin

  end.

    其中函数:Triple:把传入值加三
              Double:把传入值加二
              Triple1:把传入值加三并显示提示
              Double1:把传入值加二并显示提示

    从这个例子中可以看出DLL 程序的几个规则:

    1) 在DLL 程序中,输出函数必须被声明为stdcall,以使用标准的Win32 参数传递技术来代替优化的Register。
 
    (说明:在Delphi中Register方式是缺省的调用约定,这个约定尽量采用寄存器来传递参数,传递次序从左到右,最多可用到3个CPU 的寄存器,如果参数多于3 个,剩下的就通过栈来传送,使用寄存器传送可保证参数传递的速度最快。
    而stdcall 方式是通过Windows 的标准调用来传递参数,传递秩序从左到右,这种方式适合调用Windows 的API ,在DLL 中,当然要使用这种方式)。

    2)所有的输出函数都必须列在exports子句下面,这使的子例程在DLL外部就可以看到。

   exports

     Triple name 'Tr',
     Double name 'Do',
     Triple1 name 'TrM',
     Double1 name 'DoM';
   
    列出了用户使用这个函数的接口名字。虽然别名不是必须的,但最好给个别名,以便用户程序更容易找到这个函数,同时还要指出,Delphi 6.0取消了Delphi 5.0中允许使用的index ,如果还用Index来指明接口名字,Delphi 6.0中将提示错误。
    实例中给出了两种提示方法,主要想说明一个问题:
    showmessage(''),是VCL 提供的函数,由于多次编译VCL,做出的程序会比较大。
    而messagebox(0,'','',mb_ok)  是Windows提供的API 函数,做出的程序会比较小。
    这就是说,编写DLL 程序的时候,要尽量避免多次编译VCL 。作为一个实例,这里把两种方法都列出来了。

    保存

    编译:Projrct---Build Mydll

    这就完成了一个简单的动态连接库的编写。

    二、动态连接库的调用
    首先在implementation下做调用声明

const
  gdi32='mydll.dll';

function triple(n:integer):integer;stdcall;external gdi32 name 'Tr';
function Double(N:Integer):integer;stdcall;external gdi32 name 'Do';
function triple1(n:integer):integer;stdcall;external gdi32 name 'TrM';
function Double1(N:Integer):integer;stdcall;external gdi32 name 'DoM';

    以后程序中就可以作为普通的函数使用了,例如:

procedure TForm1.Button1Click(Sender: TObject);
var N:integer;
begin
  N:=updown1.position;
  edit1.text:=inttostr(triple(N));
end;

    第二节 DLL 中的Delphi窗体
    一、在DLL 中放置窗的的方法
    在DLL 中,除了放置标准的函数和过程以外,也可以放置已经做好的的delphi窗体,也可以把做好的窗体供其它程序使用,方法是:

   1)首先按普通方法制作窗体,不过在interface区域,对接口函数做如下声明

   function Createform(capt:string):string;stdcall;
   
   2)在implementation下加入接口函数

function Createform(capt:string):string;stdcall;
var  Form1: TForm1;
begin
  form1:=Tform1.Create(application);
  form1.show;
  form1.caption:=capt;
end;


  3)制作DLL 动态连接库,但要声明:

uses
  unit1 in 'unit1.pas';

exports

{写入接口标示符}
Createform name 'Myform';

  4)调用窗体的程序按普通方法制作,但是 在implementation下首先声明要调用的DLL函数

const
  gdi32='myFormdll.dll';
  function Createform(capt:string):string;stdcall;external gdi32 name 'Myform';


procedure TForm3.Button1Click(Sender: TObject);
var n,m:string;
begin
  m:='我的窗体';
  Createform(m);
end;

    二、DLL 中的调用窗体时的数据传递
    在窗体调用时,可以用普通的函数方法传递数据,下面举个例子。

    1)建立窗体
    做一个改变颜色窗体,放在DLL 中,可以用普通的方法来做,但要作如下声明:

    function mycolor(col:longint):longint;stdcall;
    function Getcolor:longint;stdcall;

    其中,mycolor为构造窗体;Getcolor为传递颜色数据。
    在implementation区声明一个窗体内全局的变量

    var color1:longint;

    下面写出相应的程序

function mycolor(col:longint):longint;stdcall;
var  Form1: TForm1;
begin
  form1:=Tform1.Create(application);
  form1.show;
  form1.panel1.Color:=col;
  form1.edit1.Text:=inttostr(form1.panel1.Color);
  result:=color1;
end;


function Getcolor:longint;stdcall;
begin
  result:=color1;
end;


procedure TForm1.ScrollBar1Change(Sender: TObject);
begin
  panel2.Color:=RGB(ScrollBar1.Position,ScrollBar2.Position,ScrollBar3.Position);
  edit2.Text:=inttostr(panel2.Color);
  color1:=panel2.Color;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
   Free;  //析构Form1
end;

    2)建立动态连接库
    运行成功后,再建立动态连接库:

library FormDLL;

{从文件调入}
uses
  unit1 in 'unit1.pas';

exports

{写入接口标示符}
Mycolor name 'My',
Getcolor name 'Get';

begin
end.

    3)建立调用的程序
    首先声明要调用的DLL函数

const
  gdi32='formDll.dll';
  function Mycolor(col:longint):longint;stdcall;external gdi32 name 'My';
  function Getcolor:longint;stdcall;external gdi32 name 'Get';

    然后写出相应的程序

procedure TForm1.Button1Click(Sender: TObject);
begin
  Mycolor(color);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
   color:=getcolor;
end;

    我们可以看到,在改变颜色的窗体中做了颜色变化后,当前窗体的颜色将发生变化。
   
    三、在Visual Basic应用程序中调用Delphi DLL(略。以后补全)  
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 快递没有当面验收后发现损坏怎么办 支付宝电脑付款风控异常怎么办 京东买东西地址填错了怎么办 商场卖的衣服跟官网差价大怎么办 网购的衣服有好几个破洞怎么办 出租发票有牌号是假的怎么办 支付宝里的多收多保被降级了怎么办 超市购物卡余额与实际不符怎么办 发广告的公众号无法取消关注怎么办 扣扣需要手机验证码登录怎么办 驾校报了联系不了教练了怎么办 手机号被别人注册了百度网盘怎么办 注册公司云证书申请成功后怎么办 淘宝购物卖家迟迟不发货怎么办 淘宝直播顾客加购物车不下单怎么办 东方航空联程机票航班延误怎么办 别别人伸请更换手机绑定qq怎么办 绑定手机号的扣扣忘记密码怎么办 微信公众号个人主体变更公司怎么办 微信号注册成订阅号了怎么办 微信开通了企鹅影院会员怎么办 注销公众号对公账号填写错误怎么办 国外邮的东西在北京扣了手续怎么办 微信购物商城买的东西不发货怎么办 魅族手机电话图标没有了怎么办 新商盟网页新商盟网页打不开怎么办 京东商城购物车装满了怎么办 商家想入住美团没有营业执照怎么办 旅行团定好的人数临时加人该怎么办 淘宝上发货后12天未收到款怎么办 京东购买的东西烂了怎么办 苹果4s手机激活密码忘了怎么办 小米4c返回键失灵了怎么办 小米4c下面三个键失灵怎么办 谷歌浏览器打不开指定的网址怎么办 电脑上我的电脑图标没了怎么办 手机上的短信图标没了怎么办 qq密保手机被别人换了怎么办 苹果六手机很卡网络不给力怎么办 堡垒之夜卡在载入界面怎么办 登录新福建一直说网络不给力怎么办