DELPHI的DLL建立访问
- 格式:doc
- 大小:41.50 KB
- 文档页数:5
Delphi制作DLL的方法一 Dl l的制作一般步骤二参数传递三 DL L的初始化和退出清理[如果需要初始化和退出清理]四全局变量的使用五调用静态载入六调用动态载入七在DLL建立一个TF orM八在DLL中建立一个TMDIC hildF orM九示例:十 Del phi制作的Dll与其他语言的混合编程中常遇问题:十一相关资料一 Dll的制作一般分为以下几步:1在一个DL L工程里写一个过程或函数2写一个Ex ports关键字,在其下写过程的名称。
不用写参数和调用后缀。
二参数传递1参数类型最好与win dow C++的参数类型一致。
不要用DE LPHI的数据类型。
2 最好有返回值[即使是一个过程],来报出调用成功或失败,或状态。
成功或失败的返回值最好为1[成功]或0[失败].一句话,与wi ndows c++兼容。
3用stdc all声明后缀。
4最好大小写敏感。
5 无须用far调用后缀,那只是为了与w indow s 16位程序兼容。
三D LL的初始化和退出清理[如果需要初始化和退出清理]1 DL LProc[SysU tils单元的一个P ointe r]是DL L的入口。
在此你可用你的函数替换了它的入口。
但你的函数必须符合以下要求[其实就是一个回调函数]。
如下:pro cedur e Dll Enter Point(dwRe ason: DWOR D);fa r;std call;dwRe ason参数有四种类型:DL L_PRO CESS_ATTAC H:进程进入时DL L_PRO CESS_DETAC H:进程退出时DL L_THR EAD_A TTACH :线程进入时DL L_THR EAD_D ETACH :线程退出时在初始化部分写:D LLPro c :=@DLLE nterP oint;Dl lEnte rPoin t(DLL_PROC ESS_A TTACH);2如Form上有Tdc omCon necti on组件,就Uses Acti vex,在初始化时写一句CoI nitia lize(nil);3 在退出时一定保证Dco mConn ectio n.Con necte d :=False,并且数据集已关闭。
delphi创建DLL动态链接库(转载)delphi创建DLL动态链接库(转载)关键词:DLL动态链接库delphi编程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;usesSysUtils,Classes;{$R *.res}beginend.把工程名改为Mydll,并写入必要的函数library mydll;usesSysUtils,Classes,Dialogs,windows;function Triple(N:Integer):integer;stdcall;beginresult:=N+3;end;function Double(N:Integer):integer;stdcall;beginresult:=N+2;end;function Triple1(N:Integer):integer;stdcall;beginshowmessage('计算N+3');result:=N+3;end;function Double1(N:Integer):integer;stdcall;beginmessagebox(0,'计算N+2','计算N+2',mb_ok);result:=N+2;end;exportsTriple name 'Tr',Double name 'Do',Triple1 name 'TrM',Double1 name 'DoM';Triple,Double,Triple1,Double1;{$R *.RES}beginend.其中函数:Triple:把传入值加三Double:把传入值加二Triple1:把传入值加三并显示提示Double1:把传入值加二并显示提示从这个例子中可以看出DLL 程序的几个规则:1)在DLL 程序中,输出函数必须被声明为stdcall,以使用标准的Win32 参数传递技术来代替优化的Register。
delphi如何调用C#的dlldelphi如何调用C#的dll发表于2010-03-11 16:37:13 1delphi如何调用C#的dll?在你的环境变量Path中加入C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin;C:\WINNT\\Framework\v1.1.4322随便建立一个ClassLibrary编译成DLL文件切换到MS-DOS命令行下面,运行:C:\>regasm out ClassLibrary1.DLL /regfile:ClassLibrary1.reg上面的命令行是注册我们的.NET组件,并且产生了一个备用的注册表文件。
对应Windows的注册COM文件命令:regsvr32 c:\test.dll .在.NET下面,注册.NET组件就需要上面的regasm命令了然后在MS-DOS命令行下面,运行:C:\>tlbExp ClassLibrary1.dll /out:ClassLibrary1.tlb上面的命令行表示将会产生一个.NET组件的类型库有了TLB文件也就和正常的COM组件一样了,运行Delphi导入类型库文件TLB......和正常的COM调用一样•发表于 2010-03-11 17:32:21 2以前用delphi写的CS程序今天客户要加几个模块上去,刚好会点C# ,这后面模块就用C#写的编译成dll文件,在用delphi调用C#写的dll文件时折腾好阵子就有了这些经历写下来。
一、打开vs2005新建windows应用程序项目命名为SFrm,删除应用程序自动生成的Program.cs(因为我们是要生成dll文件)在窗体类新建一接口(interface SHFRM) 让窗体类实现接口代码如下:using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Data.SqlClient;using System.Drawing;using System.Text;using System.Windows.Forms;namespace SFrm{public interface SHFRM //此接口用在delphi下调用必须用到{void ShchildFrm();}public partial class Form1 : Form,SHFRM{private BindingSource bindingSource1 = new BindingSource();private SqlDataAdapter dataAdapter = new SqlDataAdapter();public Form1()InitializeComponent();}/// <summary>/// 显示窗口/// </summary>public void ShchildFrm(){Form1 frm = new Form1();frm.Show();}/// <summary>/// 按钮事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void button1_Click(object sender, EventArgs e){dataGridView1.DataSource = bindingSource1;GetData("select * from Customers");}private void GetData(string selectCommand){try{String connectionString = "Data Source=.;initial catalog=Northwind;user id =sa;pwd=";dataAdapter = new SqlDataAdapter(selectCommand, connectionString);SqlCommandBuilder commandBuilder = new SqlCommandBuilder(dataAdapter);DataTable table = new DataTable();table.Locale = System.Globalization.CultureInfo.InvariantCulture;dataAdapter.Fill(table);bindingSource1.DataSource = table;dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);}catch (SqlException){MessageBox.Show("To run this example, replace the value of the " +"connectionString variable with a connection string that is " +"valid for your system.");}}}}右击项目名在属性对话框中更改输出类型为”类库” 在界面点击程序集信息按钮如下图:使程序集com可见必须选中完成dll文件生成二.DotNet 类库打包成COM类型库(在vs命令行执行如下操作)Tlbexp.exe SFrm.dll /out: SFrm.tlb三.注册COM类型库Regasm.exe SFrm.dll四.Delphi导入类型库Delpi 中,Project -> Import Type Library ,选中类型库:dotnet2com.tlb,生成 DotNet2Com_TLB 单元文件。
Delphi中控制Word,xml,dll等操作DLL的建立与调用[转]动态链接库是一个能够被应用程序和其它的DLL调用的过程和函数的集合体,它里面包含的是公共代码或资源。
由于DLL代码使用了内存共享技术,在某些地方windows也给了DLL一些更高的权限,因而DLL中可以实现一些一般程序所不能实现的功能,如实现windows的HOOK、ISAPI等。
同时,DLL还为不同语言间代码共享提供了一条方便的途径。
因而DLL在编程时应用较为广泛,本文将介绍如何在Delphi 中建立和使用DLL。
一.DLL 库内存共享机制从使用效果看,DLL和unit 很像,它们都可以被别的工程模块所调用,但二者在内部的实现机制上确存在着差别。
如果一个程序模块中用uses语句引用了某个unit,编译程序在编译该模块时,便会连同unit一起编译,并把编译后的可执行代码链接到本程序模块中,这就是一个程序模块能够调用所引用unit中过程和函数的原因。
当同一个unit被多个工程所引用时,则每个工程中都含有该unit的可执行代码,当含有该unit的多个工程同时执行时,unit的可执行代码会随不同工程而多次被调入内存,造成内存资源的浪费。
DLL则不同,它即使被某个工程调用,编译后仍是独立的。
也就是说编译后,一个DLL库形成一个单独的可执行文件,而不与任何其它的可执行文件连接在一起,因而DLL库并不从属于某个特定的工程,当多个工程调用同一个DLL库时只有第一个工程把DLL库调入内存,其余工程并不重复调入同一个DLL库到内存,而是到同一个共享内存区读取。
并且,DLL的执行代码是在程序运行期间动态调入的,而不是如unit在程序运行时就与整个工程一起调入内存。
这样便可消除unit带来的相同代码多处占用内存的弊病。
二 Delphi中DLL库的建立在Delphi环境中,编写一个DLL同编写一个一般的应用程序并没有太大的区别。
事实上作为DLL主体的DLL函数的编写,除了在内存、资源的管理上有所不同外,并不需要其它特别的手段。
标题:Delphi中使用DLL调用及结构参数传递的方法一、引言在Delphi中,我们经常需要使用动态信息库(DLL)来实现对外部功能的调用。
而在调用DLL时,有时需要传递结构参数,本文将介绍在Delphi中使用DLL进行结构参数传递的方法。
二、调用DLL1. 静态信息和动态信息在Delphi中,我们可以通过静态信息和动态信息两种方式调用DLL。
静态信息是将DLL文件直接嵌入到可执行文件中,而动态信息则是在程序运行时加载DLL文件。
一般来说,动态信息是更为常用的方式。
2. 使用动态信息调用DLL在Delphi中使用动态信息调用DLL,一般需要使用`LoadLibrary`函数加载DLL文件,然后使用`GetProcAddress`函数获取DLL中的函数位置区域,最后通过指针调用DLL函数。
示例代码如下:```delphivarhDLL: THandle; // DLL句柄addFunc: function(a, b: Integer): Integer; stdcall; // DLL函数指针beginhDLL := LoadLibrary('MyDll.dll'); // 加载DLLif hDLL <> 0 thenbegin@addFunc := GetProcAddress(hDLL, 'Add'); // 获取DLL中的Add函数位置区域if Assigned(addFunc) thenbegin// 调用DLL函数Result := addFunc(1, 2);end;FreeLibrary(hDLL); // 释放DLLend;end;```三、结构参数传递在DLL调用中,有时我们需要传递结构参数,即将自定义的结构体作为函数参数传递给DLL中的函数。
下面将介绍在Delphi中如何实现结构参数的传递。
1. 定义结构体我们需要在Delphi中定义需要传递的结构体。
Delphi动态与静态调用DLL(最好的资料)摘要:本文阐述了 Windows 环境下动态链接库的概念和特点,对静态调用和动态调用两种调用方式作出了比较,并给出了 Delphi 中应用动态链接库的实例。
一、动态链接库的概念动态链接库( Dynamic Link Library ,缩写为 DLL )是一个可以被其它应用程序共享的程序模块,其中封装了一些可以被共享的例程和资源。
动态链接库文件的扩展名一般是 dll ,也有可能是 drv 、 sys 和 fon ,它和可执行文件( exe )非常类似,区别在于 DLL 中虽然包含了可执行代码却不能单独执行,而应由 Windows 应用程序直接或间接调用。
动态链接是相对于静态链接而言的。
所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分。
换句话说,函数和过程的代码就在程序的 exe 文件中,该文件包含了运行时所需的全部代码。
当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源。
而动态链接所调用的函数代码并没有被拷贝到应用程序的可执行文件中去,而是仅仅在其中加入了所调用函数的描述信息(往往是一些重定位信息)。
仅当应用程序被装入内存开始运行时,在 Windows 的管理下,才在应用程序与相应的 DLL 之间建立链接关系。
当要执行所调用 DLL 中的函数时,根据链接产生的重定位信息, Windows 才转去执行 DLL 中相应的函数代码。
一般情况下,如果一个应用程序使用了动态链接库, Win32 系统保证内存中只有 DLL 的一份复制品,这是通过内存映射文件实现的。
DLL 首先被调入 Win32 系统的全局堆栈,然后映射到调用这个 DLL 的进程地址空间。
在 Win32 系统中,每个进程拥有自己的 32 位线性地址空间,如果一个 DLL 被多个进程调用,每个进程都会收到该 DLL 的一份映像。
一、开始你的第一个DLL专案1.File->Close all->File->New﹝DLL﹞代码://自动产生Code如下library Project2;//这有段废话usesSysUtils,Classes;{$R*.RES}beginend.2.加个Function进来:代码:library Project2;usesSysUtils,Classes;Function MyMax(X,Y:integer):integer;stdcall; beginif X>Y thenResult:=XelseResult:=Y;end;//切记:Library的名字大小写没关系,可是DLL-Func的大小写就有关系了。
//在DLL-Func-Name写成MyMax与myMAX是不同的。
如果写错了,立即//的结果是你叫用到此DLL的AP根本开不起来。
//参数的大小写就没关系了。
甚至不必同名。
如原型中是(X,Y:integer)但引//用时写成(A,B:integer),那是没关系的。
//切记:要再加个stdcall。
书上讲,如果你是用Delphi写DLL,且希望不仅给//Delphi-AP也希望BCB/VC-AP等使用的话,那你最好加个Stdcall;的指示//参数型态:Delphi有很多种它自己的变量型态,这些当然不是DLL所喜欢的//,Windows/DLL的母语应该是C。
所以如果要传进传出DLL的参数,我们//尽可能照规矩来用。
这两者写起来,后者会麻烦不少。
如果你对C不熟//的话,那也没关系。
我们以后再讲。
{$R*.RES}beginend.3.将这些可共享的Func送出DLL,让外界﹝就是你的Delphi-AP啦﹞使用:光如此,你的AP还不能用到这些,你还要加个Exports才行。
代码:{$R*.RES}exportsMyMax;beginend.二、进行测试:开个新application:1.加个TButton代码:ShowMessage(IntToStr(MyMax(30,50)));2.告知Exe到那里抓个Func代码://在Form,interface,var后加Function MyMax(X,Y:integer):integer;stdcall;external'MyTestDLL.dll';//MyTestDLL.dll为你前时写的DLL项目名字//DLL名字大小写没关系。
delphi dll函数调用方法
1. 创建一个新的 Delphi 项目,选择类型为“库”(Library),这个
项目将成为你的 DLL 项目。
2.在DLL项目中创建需要导出的函数。
例如:
function Add(a, b: Integer): Integer;。
begin。
Result := a + b;。
end;。
exports。
Add;。
3. 打开“项目选项”对话框,在“输出”选项卡中设置库文件的生
成方式,例如选择“库文件(.dll)”和“Win32平台”。
4.编译DLL项目并生成DLL文件。
5. 创建一个新的 Delphi 项目,用于测试你的 DLL。
6. 在测试项目中使用“外部函数”(External)语句来导入 DLL 中的
函数。
例如:
function Add(a, b: Integer): Integer; external 'MyDLL.dll';。
7.编译测试项目并运行测试。
8. 如果测试成功,则意味着你已经成功地在 Delphi 中调用了 DLL
中的函数。
Delphi中高级DLL的编写和调用2001年06月14日10:54:38 赛迪网苏涌根据Delphi提供的有关DLL编写和调用的帮助信息,你可以很快完成一般的DLL编写和调用的应用程序。
本文介绍的主题是如何编写和调用能够传递各种参数(包括对象实例)的DLL。
例如,主叫程序传递给DLL一个ADOConnection 对象示例作为参数,DLL中的函数和过程调用通过该对象实例访问数据库。
需要明确一些基本概念。
对于DLL,需要在主程序中包含exports子句,用于向外界提供调用接口,子句中就是一系列函数或过程的名字。
对于主叫方(调用DLL的应用程序或其它的DLL),则需要在调用之前进行外部声明,即external保留字指示的声明。
这些是编写DLL和调用DLL 必须具备的要素。
另外需要了解Object Pascal 中有关调用协议的内容。
在Object Pascal 中,对于过程和函数有以下五种调用协议:指示字参数传递顺序参数清除者参数是否使用寄存器register 自左向右被调例程是pascal 自左向右被调例程否cdecl 自右向左调用者否stdcall 自右向左被调例程否safecall 自右向左被调例程否这里的指示字就是在声明函数或过程时附加在例程标题之后的保留字,默认为register,即是唯一使用CPU寄存器的参数传递方式,也是传递速度最快的方式;pascal: 调用协议仅用于向后兼容,即向旧的版本兼容;cdecl: 多用于C和C++语言编写的例程,也用于需要由调用者清除参数的例程;stdcall: 和safecall主要用于调用W indows API 函数;其中safecall还用于双重接口。
在本例中,将使用调用协议cdecl ,因为被调用的DLL中,使用的数据库连接是由主叫方传递得到的,并且需要由主叫方处理连接的关闭和销毁。
下面是DLL完整源程序和主叫程序完整源程序。
包括以下四个文件:Project1.DPR {主叫程序}Unit1.PAS {主叫程序单元}Project2.DPR {DLL}Unit2.PAS {DLL单元}{---------- DLL 主程序Project2.DPR ----------}library Project2;usesSysUtils,Classes,Unit2 in 'Unit2.pas' {Form1};{$R *.RES}{ 下面的语句用于向调用该DLL的程序提供调用接口}exportsDoTest; { 过程来自单元Unit2 }beginend.{---------- DLL中的单元Unit2.PAS ----------}unit Unit2;interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, Db, ADODB, StdCtrls, Menus;typeTForm1 = class(TForm)ADOConnection1: TA DOConnection;{ 本地数据库连接}Memo1: TMemo; { 用于显示信息}privatepublicend;{ 该过程向外提供}procedure DoTest(H: THandle; { 获得调用者的句柄}A Conn: TADOConnection;{ 获得调用者的数据库连接}S: string; { 获得一些文本信息}N: Integer); { 获得一些数值信息}cdecl; { 指定调用协议}implementation{$R *.DFM}procedure DoTest(H: THandle; AConn: TA DOConnection; S: string; N: Integer); beginApplication.Handle := H; { 将过程的句柄赋值为调用者的句柄}{ 上面语句的作用在于,DLL的句柄和调用者的句柄相同,在任务栏中就不会} { 各自出现一个任务标题了。
动态链接库是一个能够被应用程序和其它的DLL调用的过程和函数的集合体,它里面包含的是公共代码或资源。
由于DLL代码使用了内存共享技术,在某些地方windows 也给了DLL一些更高的权限,因而DLL中可以实现一些一般程序所不能实现的功能,如实现windows的HOOK、ISAPI等。
同时,DLL还为不同语言间代码共享提供了一条方便的途径。
因而DLL在编程时应用较为广泛,本文将介绍如何在 Delphi 中建立和使用DLL。
一.DLL 库内存共享机制
从使用效果看,DLL和unit 很像,它们都可以被别的工程模块所调用,但二者在内部的实现机制上确存在着差别。
如果一个程序模块中用uses语句引用了某个unit,编译程序在编译该模块时,便会连同unit一起编译,并把编译后的可执行代码链接到本程序模块中,这就是一个程序模块能够调用所引用unit中过程和函数的原因。
当同一个unit被多个工程所引用时,则每个工程中都含有该unit的可执行代码,当含有该unit的多个工程同时执行时,unit的可执行代码会随不同工程而多次被调入内存,造成内存资源的浪费。
DLL则不同,它即使被某个工程调用,编译后仍是独立的。
也就是说编译后,一个DLL库形成一个单独的可执行文件,而不与任何其它的可执行文件连接在一起,因而DLL库并不从属于某个特定的工程,当多个工程调用同一个DLL 库时只有第一个工程把DLL库调入内存,其余工程并不重复调入同一个DLL库到内存,而是到同一个共享内存区读取。
并且,DLL 的执行代码是在程序运行期间动态调入的,而不是如unit在程序运行时就与整个工程一起调入内存。
这样便可消除unit带来的相同代码多处占用内存的弊病。
二 Delphi中DLL库的建立
在Delphi环境中,编写一个DLL同编写一个一般的应用程序并没有太大的区别。
事实上作为DLL主体的DLL函数的编写,除了在内存、资源的管理上有所不同外,并不需要其它特别的手段。
一般工程文件的格式为:
program工程标题;
uses子句;
程序体
而DLLs工程文件的格式为:
library 工程标题;
uses 子句;
exprots 子句;
绦蛱?
它们主要的区别有两点:
1.一般工程文件的头标用program关键字,而DLL工程文件头标用library 关键字。
不同的关键字通知编译器生成不同的可执行文件。
用program关键字生成的是.exe文件,而用library关键字生成的是.dll文件;
2.假如DLL要输出供其它应用程序使用的函数或过程,则必须将这些函数或过程列在exports子句中。
而这些函数或过程本身必须用export编译指令进行编译。
在Delphi主菜单file 中选new...项,在弹出的窗口中双击DLL图标,便会自动给出DLL源模块框架,如下:
Library project1;
{...注释...}
uses
SysUtils, Classes;
begin
end.
接下来便可在USES和begin之间加入想在该DLL中实现的过程和函数的定义,并用export和exprots保字把它们引出,以便别的模块引用,在begin和end之间加入初始化代码,初始化代码是用来对DLL变量初始化。