当前位置:文档之家› delphi之调用外部dll中的函数

delphi之调用外部dll中的函数

delphi之调用外部dll中的函数
delphi之调用外部dll中的函数

分早绑定和晚绑定两种。

早绑定的代码如下:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

TForm1 = class(TForm)

Button1: TButton;

procedure Button1Click(Sender: TObject);

private

{ Private declarations }

public

{ Public declarations }

end;

var

Form1: TForm1;

//MB 函数的声明:

function MB(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;

implementation

{$R *.dfm}

{调用外部 DLL 中的函数,譬如调用系统 user32.dll 中的 MessageBoxA}

//function MB(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; // stdcall; external user32 name 'MessageBoxA';

{其中 user32 是 Delphi 定义的常量 'user32.dll',可以直接写成:}

//function MB(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; // stdcall; external 'user32.dll' name 'MessageBoxA';

{name 后面说明函数的真实名字}

{external 子句说明单元载入时就加载函数,也就是早绑定;如果晚绑定需要用LoadLibrary}

{stdcall 指令表示参数传递是从右到左(Pascal则反之),不通过CPU寄存器

传递}

{4个参数的数据类型可以使用对应的 Delphi 数据类型,譬如:}

//function MB(hWnd: LongWord; lpText, lpCaption: PChar; uType: LongWord): Integer;

// stdcall; external 'user32.dll' name 'MessageBoxA';

{或者是:}

//function MB(hWnd: Cardinal; lpText, lpCaption: PChar; uType: Cardinal): Integer;

// stdcall; external 'user32.dll' name 'MessageBoxA';

{如果函数在此单元声明后,需要给其他单元调用,需要先在 interface 区声明:} //function MB(hWnd: Cardinal; lpText, lpCaption: PChar; uType: Cardinal): Integer;

// stdcall;

{本例已经这样做了,如果要测试其他几种情况,需要先注释掉它}

{然后在 implementation 区,说明函数的来源:}

function MB; external 'user32.dll' name 'MessageBoxA';

//调用测试:

procedure TForm1.Button1Click(Sender: TObject);

var

t,b: PChar;

begin

t := '标题';

b := '内容';

MB(0,b,t,0);

end;

end.

晚绑定的例子:

unit Unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

Dialogs, StdCtrls;

type

//晚绑定,也就是动态调用外部函数主要用以下三个命令:

//LoadLibrary:获取 DLL

//GetProcAddress:获取函数

//FreeLibrary:释放

//定义一个过程类型,参数要和需要的函数一致

TMB = function(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall;

TForm1 = class(TForm)

Button1: TButton;

procedure Button1Click(Sender: TObject);

procedure FormCreate(Sender: TObject);

procedure FormDestroy(Sender: TObject);

private

MB: TMB; {声明函数 MB}

inst: LongWord; {声明一个变量来记录要使用的 DLL 句柄}

public

{ Public declarations }

end;

var

Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);

begin

inst := LoadLibrary('user32.dll');

if inst <> 0then

MB := GetProcAddress(inst, 'MessageBoxW');

// MB := GetProcAddress(inst, 'MessageBoxA'); {Delphi 2009 之前的版本用这句}

end;

//调用测试:

procedure TForm1.Button1Click(Sender: TObject);

var

t,b: PChar;

begin

t := '标题';

b := '内容';

MB(0, b, t, 0);

end;

procedure TForm1.FormDestroy(Sender: TObject);

begin

FreeLibrary(inst); {记得释放}

end;

end.

创建并调用dll

//通过 DLL Wizard 建立:

library TestDLL;

uses

SysUtils,

Classes,

Dialogs;

{$R *.res}

//建立过程

procedure Test;

begin

ShowMessage('TestDLL.Test');

end;

//输出

exports

Test;

begin

end.

//在其他工程调用,如果不在一个工程组,需要在相同目录下、System32下或指定路径;

//声明可以在实现区或接口区,这里的函数名要一致,甚至大小写。

//调用测试:

procedure Test; external 'TestDLL.dll';

procedure TForm1.Button1Click(Sender: TObject);

begin

Test; end;

在VB中调用DLL的方法

1制作好DLL之后,就可以用VB调用它,实现VB调用C程序。VB程序要使用DLL中的函数,首先必须要有特殊的声明,用Declare声明语句在窗体级或模块级或全局模块的代码声明段进行声明,将动态链接库中的函数声明到VB中,供VB程序调用。 语句格式为:Declare Sub过程名Lib[Alias"别名]([ByVal参数AS类型]),或为Declare Function函数名Lib[Alias"别名]([ByVal参数AS类型])AS类型在声明中首先用Declare 关键字表示声明DLL中的函数。在C语言中有的函数类型为VOID,它表示不具有返回值,则必须用关键字Sub将其声明成过程。有的函数具有返回值,则必须用关键字Function将其声明成函数,并且在声明语句的最后要用AS关键字指明函数返回值的类型。 例如上面的ADD.DLL在VB中就可以声明为: Declare Function ADD Lib“c:\ADD.dll”(ByVal X AS Integer,ByVal Y AS Integer,ByVal filein asstring)AS Integer 通过此声明语句将函数ADD声明到VB中,便可直接调用。 2、dll文件中的函数好像是C语言写的, //函数名:int__stdcall GetMacNo(int*MacNo) //功能:获取卡机的卡机号(单机时) //参数:MacNo[0]-被读出的卡机号 //返回值:0-成功, //2-PC接收超时, //3-应答错误 dll的文件名是COMM232.dll 函数的形参int*MacNo是指针吗? 在VB中应该怎么声明和调用该函数? VB里也可以定义指针吗? 问题补充:vb调用dll文件中的函数我是会的,但这儿的形参有一个星号才不知是怎么一回事, 我是这样声明的对吗? Public Declare Function GetMacNo Lib"COMM232.dll"(ByVal MacNo As Integer)As Integer 又应该怎么调用呢?要先定义一个指针的变量再传给*MacNo还是要怎么做? 都说了MacNo是被读出的卡机号,那么就是传址的了。 dim l as integer dim m as integer l=GetMacNo(m) if l=0then label1.caption="卡机号:"&m elseif l=2then msgbox"PC接收超时" elseif l=3then msgbox"应答错误" end if

DELPHI中如何调用API,可举例说明

DELPHI中如何调用API,可举例说明 第一部分Delphi知识1. 如果一个元件希望放到IDE的元件面板上,它必须从________类派生,如果一个元件能作为其它元件的容器,它必须从_____________类派生,如果一个元件在运行时可见,它必须从___________________类派生(A)TGraphicControl (B)TWinContr 1、rtl70.bpl是什么?有什么用? 2、delphi的Package相对dll有什么优点? 3、以下的记录(结构)变量在内存占多少字节?type a = packed record v1: Byte; v2: Word; v3: string[16]; v4: Double; v5: string; v6: TForm; end; 4、以下的写法是否正确?type a 1.您为什么选择软件开发这个行业?(30字左右简写); 2.如果有您解决不了的软件问题您会采取什么样的解决措施; 3.a.请您写出Object Pascal所支持的数据类型;b.请您写出Shl、Shr、Xor、Not 的数学表示法; 4.请您写出VCL结构层次(以TObject开始,最少五层);5 二.是非题(共20道)1.从主菜单上选择Project|Syntax Check 菜单选项,Delphi将编译从上次编译后有改动的任何单元,并报出遇到的错误。()2.Delphi的VCL对象有些是指针,从堆栈中分配空间,有些则不是。()3.粘贴时,如果作为容器的组件已被选择,

剪贴 一.选择题(共40道)1.用户开发程序时需要经常在窗体和编辑器窗口之间来回切换,可使用快捷键()。A、F12和F11 B、F12和F13 C、F12和Ctrl+F12 D、F12和Alt+F12 E、F12和Shift+F12 2.某函数如下:Function check(n,k:Integer):Integer; Var m:Integer; Beg 编程语言:delphi7.0或Vc++6.0 时间:4小时内环境:可参考帮助文档,但不能上网查资料1、编程查找指定目录下所有EXE 文件,并将其全路径存入Result.txt中,要求用递归。2、采用SOCKET(可用SOCKET API或delphi Socket控件)实现点对点传输大文件,要求不能掉

C++中DLL函数的导出和导入

1.使用DEF 文件从DLL 导出 模块定义(.def) 文件是包含一个或多个描述DLL 各种属性的Module 语句的文本文件。如果不使用__declspec(dllexport)关键字导出DLL 的函数,则DLL 需要 .def 文件。 .def 文件必须至少包含下列模块定义语句: 文件中的第一个语句必须是LIBRARY 语句。此语句将 .def 文件标识为属于DLL。LIBRARY 语句的后面是DLL 的名称。链接器将此名称放到DLL 的导入库中。 EXPORTS 语句列出名称,可能的话还会列出DLL 导出函数的序号值。通过在函数名的后面加上@ 符和一个数字,给函数分配序号值。当指定序号值时,序号值的范围必须是从1 到N,其中N 是DLL 导出函数的个数。如果希望按序号导出函数,请参见按序号而不是按名称从DLL 导出函数以及本主题。 例如,包含实现二进制搜索树的代码的DLL 看上去可能像下面这样: LIBRARY BTREE EXPORTS Insert @1 Delete @2 Member @3 Min @4 如果使用MFC DLL 向导创建MFC DLL,则向导将为您创建主干 .def 文件并将其自动添加到项目中。添加要导出到此文件的函数名。对于非MFC DLL,必须亲自创建 .def 文件并将其添加到项目中。 如果导出C++ 文件中的函数,必须将修饰名放到 .def 文件中,或者通过使用外部“C”定义具有标准C 链接的导出函数。如果需要将修饰名放到 .def

文件中,则可以通过使用DUMPBIN 工具或/MAP 链接器选项来获取修饰名。请注意,编译器产生的修饰名是编译器特定的。如果将Visual C++ 编译器产生的修饰名放到 .def 文件中,则链接到DLL 的应用程序必须也是用相同版本的Visual C++ 生成的,这样调用应用程序中的修饰名才能与DLL 的 .def 文件中的导出名相匹配。 如果生成扩展DLL 并使用 .def 文件导出,则将下列代码放在包含导出类的头文件的开头和结尾: #undef AFX_DATA #define AFX_DATA AFX_EXT_DATA // #undef AFX_DATA #define AFX_DATA 这些代码行确保内部使用的MFC 变量或添加到类的变量是从扩展DLL 导出(或导入)的。例如,当使用DECLARE_DYNAMIC派生类时,该宏扩展以将CRuntimeClass成员变量添加到类。省去这四行代码可能会导致不能正确编译或链接DLL,或在客户端应用程序链接到DLL 时导致错误。 当生成DLL 时,链接器使用 .def 文件创建导出(.exp) 文件和导入库(.lib) 文件。然后,链接器使用导出文件生成DLL 文件。隐式链接到DLL 的可执行文件在生成时链接到导入库。 请注意,MFC 本身使用 .def 文件从MFCx0.dll 导出函数和类。 2.使用_declspec(dllexport) 从DLL 导出 Microsoft 在Visual C++ 的16 位编译器版本中引入了_export,使编译器得以自动生成导出名并将它们放到一个 .lib 文件中。然后,此 .lib 文件就可以像静态 .lib 那样用于与DLL 链接。

delphi之调用外部dll中的函数

分早绑定和晚绑定两种。 早绑定的代码如下: unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; //MB 函数的声明: function MB(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; stdcall; implementation {$R *.dfm} {调用外部 DLL 中的函数,譬如调用系统 user32.dll 中的 MessageBoxA} //function MB(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; // stdcall; external user32 name 'MessageBoxA'; {其中 user32 是 Delphi 定义的常量 'user32.dll',可以直接写成:} //function MB(hWnd: HWND; lpText, lpCaption: PChar; uType: UINT): Integer; // stdcall; external 'user32.dll' name 'MessageBoxA'; {name 后面说明函数的真实名字} {external 子句说明单元载入时就加载函数,也就是早绑定;如果晚绑定需要用LoadLibrary} {stdcall 指令表示参数传递是从右到左(Pascal则反之),不通过CPU寄存器

VB如何调用dll函数

VB如何调用dll函数 2008-01-10 17:17 開始習慣孤單 | 分类:VB| 浏览13089次 假如我有个DLL,名为 asdfg.dll 它里面有一个函数 zxc(参数1,参数2) 我要用这个函数,该怎么写? 请高手帮我写出脚本,有时间的话请再加上注释 谢谢!! 2008-01-10 19:50 提问者采纳 1.在工程-引用中将asdfg.dll引用过来 2.dim AAA as asdfg 'asdfg是类模块的名称 Private Sub Form_Load() dim x Set AAA = New asdfg x = AAA.zxc(参数1,参数2)'参数1,2自己写 End Sub 建议你了解一下下面dll的制作方法,理解就更透彻了。下面内容来自百度。 1.新建一个ActiveX Dll,工程名字为vbmytestdll,类模块

名字为mytestdll 2.类模块内容只有一个函数,主要返回DLL的HELLO WORLD Public Function dlltest1() As String dlltest1 = "HELLO WORLD" End Function 3.保存,生成DLL,名字为 vbmytestdll.dll 4.新建一个EXE工程,在菜单: 工程---引用---浏览里找到vbmytestdll.dll,把它引用进来 5.EXE工程代码如下: Option Explicit Dim testdll As mytestdll'类模块名字 Private Sub Form_Load() Set testdll = New mytestdll 'DLL的一个新实例 Me.Caption = testdll.dlltest1 '我的标题=返回DLL的HELLO WORLD

易语言中调用DLL使用说明

易语言中调用DLL使用说明 基本说明 本文所描述的部分功能需易语言4.01或以上版本支持。 “在易语言中调用DLL”包含两方面的内容:调用Windows系统API函数;调用普通DLL函数。 下文用到的“调用API”或“调用DLL”等字眼,除非特别注明,一般都是指以上两方面之一或之和,视上下文而定。绝大多数情况下,无需明确区分调用的是系统API还是普通DLL。 目前易语言只支持以stdcall方式调用DLL中的导出函数。 Windows系统API一般都是以stdcall调用方式导出的,故在易语言中调用它们时通常不必考虑函数调用方式的问题。而普通DLL有可能导出“非stdcall调用方式”(比如cdecl)的函数,调用时需要特别注意。一般而言,考虑到通用性,DLL开发者都会选择导出以sdtcall方式调用的函数。(支持生成DLL的编程语言通常都支持导出stdcall调用方式的函数,具体实现请参考各编程语言手册。) 易语言编译生成的DLL,其导出函数全部为stdcall调用方式,所以在易语言中调用易语言生成的DLL不存在问题。 目前在易语言中调用DLL时只支持1字节对齐的结构(自定义数据类型) 如果DLL命令的某个参数或参数的某个成员是结构类型(自定义数据类型),则其对齐方式必须是1字节对齐。Windows系统API中所用到的结构都是1字节对齐的,故在调用API时不受此限制。但如果想用其它编程语言生成DLL供易语言调用且数据类型中包含了1或2字节数据长度的成员(如字符型或短整数),就需要考虑结构的1字节对齐。

在Delphi中,可以这样定义1字节对齐的结构(结构在Delphi中称为record): 在其它编程语言或编译器中的定义方式请参考各自的编程手册。 目前易语言支持调用任意复杂的DLL命令 只要满足了前面的两个条件——调用方式为stdcall,参数结构为1字节对齐——易语言支持调用任意复杂的DLL命令:参数除了可以是基本数据类型或普通结构类型外,还可以是基本类型地址或基本类型数组,也可以是结构类型地址或结构类型数组,结构类型的成员中还可以包含任意数量和任意层次的其它结构、结构地址、结构数组,等等。 DLL命令调用表 要在易语言中调用Windows API或普通DLL中的导出函数,必须首先在易语言中对该函数进行声明,声明的方式就是颇具易语言特色的“填写‘DLL命令调用表’”。“DLL命令调用表”正确填写完毕之后,就可以象调用普通易语言子程序一样调用DLL命令了。 下面重点说明“DLL命令调用表”的填写。 在易语言中,选择菜单“插入→DLL命令”即可插入一个空白的“DLL命令调用表”。当然还有其它操作方式,请参考易语言相关操作手册。

如何用delphi制作DLL动态库方法

用Delphi制作DLL的方法 一Dll的制作一般步骤 二参数传递 三DLL的初始化和退出清理[如果需要初始化和退出清理] 四全局变量的使用 五调用静态载入 六调用动态载入 七在DLL建立一个TForM 八在DLL中建立一个TMDIChildForM 九示例: 十Delphi制作的Dll与其他语言的混合编程中常遇问题: 十一相关资料 一Dll的制作一般分为以下几步: 1 在一个DLL工程里写一个过程或函数 2 写一个Exports关键字,在其下写过程的名称。不用写参数和调用后缀。 二参数传递 1 参数类型最好与window C++的参数类型一致。不要用DELPHI的数据类型。 2 最好有返回值[即使是一个过程],来报出调用成功或失败,或状态。成功或失败的返回值最好为1[成功]或0[失败].一句话,与windows c++兼容。 3 用stdcall声明后缀。 4 最好大小写敏感。 5 无须用far调用后缀,那只是为了与windows 16位程序兼容。 三DLL的初始化和退出清理[如果需要初始化和退出清理] 1 DLLProc[SysUtils单元的一个Pointer]是DLL的入口。在此你可用你的函数替换了它的入口。但你的函数必须符合以下要求[其实就是一个回调函数]。如下: procedure DllEnterPoint(dwReason: DWORD);far;stdcall; dwReason参数有四种类型: DLL_PROCESS_ATTACH:进程进入时 DLL_PROCESS_DETACH进程退出时 DLL_THREAD_A TTACH 线程进入时 DLL_THREAD_DETACH 线程退出时 在初始化部分写: DLLProc := @DLLEnterPoint; DllEnterPoint(DLL_PROCESS_ATTACH); 2 如Form上有TdcomConnection组件,就Uses Activex,在初始化时写一句CoInitialize (nil); 3 在退出时一定保证DcomConnection.Connected := False,并且数据集已关闭。否则报地址错。 四全局变量的使用 在widnows 32位程序中,两个应用程序的地址空间是相互没有联系的。虽然DLL在内存中是一份,但变量是在各进程的地址空间中,因此你不能借助dll的全局变量来达到两个应用

delphi中dll综合运用的例子

delphi中dll综合运用的例子(动态加载插件) 2008年01月15日星期二 10:59 1,新建dll客户端模块 ---------------dll工程文件PlugIns.dll------------------------------- library PlugIns; { Important note about DLL memory management: ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause if your DLL exports any procedures or functions that pass strings as parameters or function results. This applies to all strings passed to and from your DLL--even those that are nested in records and classes. ShareMem is the interface unit to the BORLNDMM.DLL shared memory manager, which must be deployed along with your DLL. To avoid using BORLNDMM.DLL, pass string information using PChar or ShortString parameters. } uses SysUtils, Classes, PlugInFrm in 'PlugInFrm.pas' {FrmPlugIns}; {$R *.res} //输出接口函数 exports ShowDLLForm,GetCaption; begin end. -------------新建模块PlugInFrm.pas的窗体文件--------------- unit PlugInFrm; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TFrmPlugIns = class(TForm) Label1: TLabel; private { Private declarations }

在vb中调用dll的方法

1 制作好DLL之后,就可以用VB调用它,实现VB调用C程序。VB程序要使用DLL中的函数,首先必须要有特殊的声明,用Declare声明语句在窗体级或模块级或全局模块的代码声明段进行声明,将动态链接库中的函数声明到VB中,供VB程序调用。 语句格式为:Declare Sub 过程名Lib [ Alias " 别名]([ByVal 参数AS类型]),或为Declare Function函数名Lib [Alias " 别名]([ByVal 参数AS类型])AS类型在声明中首先用Declare 关键字表示声明DLL中的函数。在C语言中有的函数类型为VOID,它表示不具有返回值,则必须用关键字Sub将其声明成过程。有的函数具有返回值,则必须用关键字Function将其声明成函数,并且在声明语句的最后要用AS关键字指明函数返回值的类型。 例如上面的ADD.DLL在VB中就可以声明为: Decl are Function ADD Lib “c:\ADD.dll” (ByVal X AS Integer, ByVal Y AS Integer ,ByVal filein asstring)AS Integer 通过此声明语句将函数ADD声明到VB中,便可直接调用。 2、dll文件中的函数好像是C语言写的, // 函数名:int __stdcall GetMacNo(int *MacNo) // 功能:获取卡机的卡机号(单机时) // 参数: MacNo[0]-被读出的卡机号 // 返回值:0-成功, // 2-PC接收超时, // 3-应答错误 dll的文件名是COMM232.dll 函数的形参int *MacNo是指针吗? 在VB中应该怎么声明和调用该函数? VB里也可以定义指针吗? 问题补充:vb调用dll文件中的函数我是会的,但这儿的形参有一个星号才不知是怎么一回事, 我是这样声明的对吗? Public Declare Function GetMacNo Lib "COMM232.dll" (ByVal MacNo As Integer) As Integer 又应该怎么调用呢?要先定义一个指针的变量再传给*MacNo还是要怎么做? 都说了MacNo是被读出的卡机号,那么就是传址的了。 dim l as integer dim m as integer l=GetMacNo(m) if l=0 then label1.caption="卡机号: " & m elseif l=2 then msgbox "PC接收超时" elseif l=3 then msgbox "应答错误" end if

delphi如何调用C#的dll

delphi如何调用C#的dll delphi如何调用C#的dll 发表于2010-03-11 16:37:13 Idelphi如何调用C#的dll ?在你的环境变量Path中加入 C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin; C:\WINNT\https://www.doczj.com/doc/2817529878.html,\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 https://www.doczj.com/doc/2817529878.html,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();}/// /// 显示窗口/// public void ShchildFrm(){Form1 frm = new Form1();frm.Show();}/// /// 按钮事件/// /// /// 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,

关于DLL动态库调用

关于DLL动态库调用小结 引言 比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。在构造软件系统时,如果将所有模块的源代码都静态编译到整个应用程序EXE 文件中,会产生一些问题:一个缺点是增加了应用程序的大小,它会占用更多的磁盘空间,程序运行时也会消耗较大的内存空间,造成系统资源的浪费;另一个缺点是,在编写大的EXE程序时,在每次修改重建时都必须调整编译所有源代码,增加了编译过程的复杂性,也不利于阶段性的单元测试。 Windows系统平台上提供了一种完全不同的较有效的编程和运行环境,你可以将独立的程序模块创建为较小的DLL(Dynamic Linkable Library)文件,并可对它们单独编译和测试。在运行时,只有当EXE程序确实要调用这些DLL模块的情况下,系统才会将它们装载到内存空间中。这种方式不仅减少了EXE文件的大小和对内存空间的需求,而且使这些DLL模块可以同时被多个应用程序使用。Windows自己就将一些主要的系统功能以DLL 模块的形式实现。 一般来说,DLL是一种磁盘文件,以.dll、.DRV、.FON、.SYS和许多以.EXE为扩展名的系统文件都可以是DLL。它由全局数据、服务函数和资源组成,在运行时被系统加载到进程的虚拟空间中,成为调用进程的一部分。如果与其它DLL之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。DLL模块中包含各种导出函数,用于向外界提供服务。DLL可以有自己的数据段,但没有自己的堆栈,使用与调用它的应用程序相同的堆栈模式;一个DLL在内存中只有一个实例;DLL实现了代码封装性;DLL的编制与具体的编程语言及编译器无关。 在Win32环境中,每个进程都复制了自己的读/写全局变量。如果想要与其它进程共享内存,必须使用内存映射文件或者声明一个共享数据段。DLL模块需要的堆栈内存都是从运行进程的堆栈中分配出来的。Windows在加载DLL模块时将进程函数调用与DLL文件的导出函数相匹配。Windows操作系统对DLL的操作仅仅是把DLL映射到需要它的进程的虚拟地址空间里去。DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有. 调用方式

在DELPHI中静态调用DLL

一、开始你的第一个DLL专案 1.File->Close all->File->New﹝DLL﹞ 代码: //自动产生Code如下 library Project2; //这有段废话 uses SysUtils, Classes; {$R*.RES} begin end. 2.加个Function进来: 代码: library Project2; uses SysUtils, Classes; Function MyMax(X,Y:integer):integer;stdcall; begin if X>Y then Result:=X else Result:=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} begin end. 3.将这些可共享的Func送出DLL,让外界﹝就是你的Delphi-AP啦﹞使用:光如此,你的AP还不能用到这些,你还要加个Exports才行。 代码: {$R*.RES} exports MyMax; begin end. 二、进行测试:开个新application: 1.加个TButton 代码: ShowMessage(IntToStr(MyMax(30,50)));

dll调用

目录 ?引言 ?调用方式 ?MFC中的DLL ?DLL入口函数 ?关于调用约定 ?关于DLL的函数 ?模块定义文件(.DEF) ?DLL程序和调用其输出函数的程序的关系 引言 比较大的应用程序都由很多模块组成,这些模块分别完成相对独立的功能,它们彼此协作来完成整个软件系统的工作。可能存在一些模块的功能较为通用,在构造其它软件系统时仍会被使用。在构造软件系统时,如果将所有模块的源代码都静态编译到整个应用程序EXE 文件中,会产生一些问题:一个缺点是增加了应用程序的大小,它会占用更多的磁盘空间,程序运行时也会消耗较大的内存空间,造成系统资源的浪费;另一个缺点是,在编写大的EXE 程序时,在每次修改重建时都必须调整编译所有源代码,增加了编译过程的复杂性,也不利于阶段性的单元测试。 W indows 系统平台上提供了一种完全不同的较有效的编程和运行环境,你可以将独立的程序模块创建为较小的DLL (Dy namic Linkab le L ibrary) 文件,并可对它们单独编译和测试。在运行时,只有当EXE 程序确实要调用这些DLL 模块的情况下,系统才会将它们装载到内存空间中。这种方式不仅减少了EXE 文件的大小和对内存空间的需求,而且使这些DLL 模块可以同时被多个应用程序使用。W indows 自己就将一些主要的系统功能以DLL 模块的形式实现。 一般来说,DLL 是一种磁盘文件,以.dll、.DRV、.FO N、.SYS 和许多以.EXE 为扩展名的系统文件都可以是DLL。它由全局数据、服务函数和资源组成,在运行时被系统加载到调用进程的虚拟空间中,成为调用进程的一部分。如果与其它DLL 之间没有冲突,该文件通常映射到进程虚拟空间的同一地址上。DLL 模块中包含各种导出函数,用于向外界提供服务。DLL 可以有自己的数据段,但没有自己的堆栈,使用与调用它的应用程序相同的堆栈模式;一个DLL 在内存中只有一个实例;DLL 实现了代码封装性;DLL 的编制与具体的编程语言及编译器无关。 在W in32 环境中,每个进程都复制了自己的读/写全局变量。如果想要与其它进程共享内存,必须使用内存映射文件或者声明一个共享数据段。DLL 模块需要的堆栈内存都是从运行进程的堆栈中分配出来的。W indows 在加载DLL

VB调用动态链接库

VB调用动态链接库-[Dll编程] 作为一种简单易用的Windows开发环境,Visual Basic从一推出就受到了广大编程人员的欢迎。它使程序员不必再直接面对纷繁复杂的Windows消息,而可以将精力主要集中在程序功能的实现上,大大提高了编程效率。但凡事有利必有弊。 VB中高度的封装和模块化减轻了编程者的负担,同时也使开发人员失去了许多访问低层API函数和直接与Windows交互的机会。因此,相比而言,VB应用程序的执行效率和功能比C/C++或Delphi生成的程序要差。为了解决这个问题,在一个大型的VB开发应用中,直接调用Windows API函数几乎是不可避免的;同时,还有可能需要程序员自己用C/C++等开发一些动态连接库,用于在VB中调用。本文主要讨论在32位开发环境Visual Basic 5.0中直接调用Windows 95 API函数或用户生成的32位动态连接库的方法与规则。 Windows动态连接库是包含数据和函数的模块,可以被其它可执行文件(EXE、DLL、OCX 等)调用。动态连接库包含两种函数:输出(exported)函数和内部(internal)函数。输出函数可以被其它模块调用,而内部函数则只能在动态连接库内部使用。尽管动态连接库也能输出数据,但实际上它的数据通常是只在内部使用的。使用动态连接库的优点是显而易见的。将应用程序的一部分功能提取出来做成动态连接库,不但减小了主应用程序的大小,提高了程序运行效率,还使它更加易于升级。多个应用程序共享一个动态连接库还能有效地节省系统资源。正因为如此,在Windows系统中,动态连接库得到了大量的使用。 一般来说,动态连接库都是以DLL为扩展名的文件,如Kernel32.dll、commdlg.dll 等。但也有例外,如16位Windows的核心部件之一GDI.exe其实也是一个动态库。编写动态连接库的工具很多,如VisualC++、BorlandC++、Delphi等,具体方法可以参见相关文档。下面只以Visual C++5.0为例,介绍一下开发应用于VisualBasic5.0的动态连接库时应注意的问题(本文中所有涉及C/C++语言或编译环境的地方,都以VC5为例;所有涉及VisualBasic的地方都以VB5 为例)。 作为一种32位Windows应用程序的开发工具,VB5生成的exe文件自然也都是32位的,通常情况下也只能调用32位的动态连接库。但是,并不是所有的32位动态库都能被VB生成的exe 文件正确地识别。一般来说,自己编写用于VB应用程序调用的动态连接库时,应注意以下几个方面的问题: 1、生成动态库时要使用__stdcall调用约定,而不能使用缺省的__cdecl调用约定;__stdcall 约定通常用于32位API函数的调用。 2、在VC5中的定义文件(.def)中,必须列出输出函数的函数名,以强制VC5系统将输出函数的装饰名(decoratedname)改成普通函数名;所谓装饰名是VC的编译器在编译过程中生成的输出函数名,它包含了用户定义的函数名、函数参数及函数所在的类等多方面的信息。由于在VC5中定义文件不是必需的,因此工程不包含定义文件时VC5就按自己的约定将用户定义的输出函数名修改成装饰名后放到输出函数列表中,这样的输出函数在VB生成的应用程序中是不能正确调用的(除非声明时使用Alias子句)。因此需要增加一个.def文件,其中列出用户需要的函数名,以强制VC5不按装饰名进行输出。 3、VC5中的编译选项"结构成员对齐方式(structure member alignment)" 应设成4字节,其原因将在后文详细介绍。 4、由于在C中整型变量是4个字节,而VB中的整型变量依然只有2个字节,因此在C中声明的整型(int)变量在VB中调用时要声明为长整型(long),而C中的短整型(short)在VB中则要声明成整型(integer);下表针对最常用的C语言数据类型列出了与之等价的Visual Basic 类型(用于32位版本的Windows)。

在Delphi编程中使用C语言代码 - 调用C语言编写的DLL文件

1、使用Visual C++ 6.0编写和链接DLL 打开Visual C++ 6.0集成开发环境,新建一个Win32 Dynamic-Link Library类型的工程CDLL,在工程中新建一个C语言源文件cdll.c。源文件中的内容如下: __declspec(dllexport) int max(int x,int y) /* 比较两个整型变量大小的函数max */ { if (x>y) return x; else return y; } 输入完毕后按下F7键来编译和链接CDLL.dll,之后可以在存放该工程的文件夹的Debug子文件夹中找到一个名为CDLL的DLL文件,该文件即以上的C语言源程序生成的DLL。 2、使用Delphi 7编写调用该DLL的应用程序 打开Delphi 7集成开发环境,在默认生成的窗体Form1上拖放3个Edit 控件Edit1、Edit2、Edit3和1个Button控件Button1,并在Object Inspector中将3个Edit控件的Text属性都清空。然后在默认生成的Unit1.pas文件的implementation后输入: function max(x,y: Integer): Integer; stdcall external 'CDLL.DLL';

返回Form1,双击Button1控件,在生成的事件处理程序中输入: Edit3.Text:=IntToStr(max(StrToInt(Edit1.Text), StrToInt(Edit2.Text))); 输入完毕后,保存这个Project。最后,将CDLL.dll文件copy到保存该Project的文件夹中。 3、测试 在Delphi集成开发环境下,按下F9来运行刚刚编写的Project。在Edit1中输入2,Edit2中输入4,然后单击Button1,可以看到Edit3中会出现4,测试成功。 4、基础知识 4.1、回调函数 软件模块之间总是存在着一定的接口,从调用方式上,可以把他们分为三类:同步调用、回调和异步调用。其中回调是一种双向调用模式,也就是说,被调用方在接口被调用时也会调用对方的接口;异步调用是一种类似消息或事件的机制,不过它的调用方向刚好相反,接口的服务在收到某种讯息或发生某种事件时,会主动通知客户方(即调用客户方的接口)。回调和异步调用的关系非常紧密,通常我们使用回调来实现异步消息的注册,通过异步调用来实现消息的通知。同步调用是三者当中最简单的,而回调又常常是异步调用的基础。 回调函数与普通函数的申明并无区别,但如果是不同的开发语言之间通过回调函数来传递与处理数据,则一定要注意在不同语言对回调函数的申明与实现时其函数调用约定必须保持一致。 4.2、函数调用约定 声明过程或函数时,可以指定调用约定(calling convention),尤其在以接口形式提供给其它语言工具使用时,则必须指定过程或函数的调用方式。 Delphi指定调用约定可以使用的指示字包括register、pascal、cdecl、stdcall 以及safecall。C/C++调用约定有stdcall、cdecl、fastcall、thiscall、naked call 等。 决定了传递给例程的参数的顺序,还影响参数从栈中的解除、参数传递时对寄存器的使用以及处理错误和异常等。缺省的调用约定是register。 下表是调用约定的简要概括:

Delphi 中的dll 封装和调用对象方法

Delphi 中的dll 封装和调用对象方法 2011-01-28 22:18 动态链接库是一种特殊格式的二进制数据文件,后缀名为.dll。它可以在程序运行时调用,并不需要进行重新编译,又由于它是完全独立的一个功能模块,使得其重用性非常好。将dll载入内存后,dll中的功能接口可以被系统中任何正在运行的应用程序所使用。具有节省空间,升级容易和高重用性等优点。 很多delphi的教材资料上讲到dll,大多都是将用dll来封装一些函数或者过程。但有时我们想把某个问题当成一个对象来处理,使程序模块化、组件化,方便团队开发、维护和更新。这时我们就需要用到dll封装和调用对象的技术,然而delphi在封装对象方面有一定的技术难度,资料也比较少,使得很多程序员认为delphi的dll不支持对象封装。下面简单分享一下我学习dll对象封装和调用的一些心得,希望能对这方面有需求的程序员一些帮助。 首先让我们认识一点,调用dll的程序只能使用与dll中对象动态绑定的方法,理解这一点是实现Dll封装和使用对象的关键。理解了这一点,我们就会想怎样才能实现与dll中对象的动态绑定呢?Delphi的接口技术为我们提供了一个好的选择,我们可以通过接口类去动态的获取dll中的对象。下面我用一个简单的demo来说明如何实现。 我建立了这样一个工程组,如下图 按如下几步进行: 1、先定义一个接口单元IDemo,代码如下: unit IDemo;

interface type IMax = interface (IInterface) function Max(num1, num2 : Integer) : Integer; end; implementation end. 建立我们需要封装的对象单元UnitMax.pas,注意看TMax继承自哪些父类,代码如下: unit UnitMax; interface uses IDemo; type TMax = class(TInterfacedObject, IMax) function Max( num1, num2 : Integer ) : Integer; end; implementation function TMax.Max(num1: Integer; num2: Integer) : Integer; begin Result := 0; if num1 > num2 then Result := num1 else Result := num2; end; end. 3、再在dll单元,输入如下代码:

相关主题
文本预览
相关文档 最新文档