社区
Delphi
帖子详情
在调用c++制作的dll时如何传入回调函数
seafer
2004-03-11 02:20:43
我想用delphi制作一个复杂的界面,而用C++来制作与某个特定库的API,这样,就形成了用c++制作的DLL。在该DLL中,因为经常要触发一些事件,因为必须把这些消息反送给delphi,我想应该是在调用DLL函数时将函数类型作为参数传入。
但是不知道delphi的函数类型与C++的函数指针之间是如何匹配的?
最好给点例子,谢谢!
...全文
337
2
打赏
收藏
在调用c++制作的dll时如何传入回调函数
我想用delphi制作一个复杂的界面,而用C++来制作与某个特定库的API,这样,就形成了用c++制作的DLL。在该DLL中,因为经常要触发一些事件,因为必须把这些消息反送给delphi,我想应该是在调用DLL函数时将函数类型作为参数传入。 但是不知道delphi的函数类型与C++的函数指针之间是如何匹配的? 最好给点例子,谢谢!
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
2 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
beyondtkl
2004-08-13
打赏
举报
回复
本质没差别 都是unsigned int
princesd
2004-08-13
打赏
举报
回复
(转载)看看这篇文章,有帮助
大家在软件开发时经常会遇到这样的情况,在不同的开发环境中为实现一些功能相同的过程,由于开发所使用的设计语言不同,因而不得不编写许多类似的代码,甚至有时要在同一个开发环境不同项目中重写代码,这就造成了很大的资源浪费。动态链接库能较好的解决这个问题,重复利用代码将大大提高了开发效率。一般,用户在应用程序中基于如下要求创建和使用DLL:
1. 在不同的可执行文件之间共享的程序;
2. 在设计应用程序时,将其拆分成各个相互独立功能部件,为以后这些功能部件各自升级提供方便的途径。
动态链接库将共享程序或功能部件做成库中的函数,形成DLL文件,其它应用程序通过使用DLL调用这些函数。在这里将对Delphi和VC中创建和使用动态链接库的方法做一介绍。Delphi和VC定义的动态链接库均可在两者的开发环境中使用。
一、 用Delphi创建DLL
Delphi的DLL创建并不复杂,下面向大家介绍Delphi的DLL创建方法。
(1)首先创建一个新的DLL项目(NewProject)project1,文件头部为:
library Project1;
(2)USES语句后面加入ExPorts语句,指明调用DLL的函数名,形式为:
exports
checkpwd name 'checkpwd';
(3)在DLL的Pas文件中Type......End后加入该DLL的函数或过程的声明,形式如下:
FunctionName(argment):Boolean;export;
该函数也可以存在于另一个pas文件中(如Unit1.pas),此时只需在项目文件中加入:
uses
Unit1 in 'Unit1.pas' {Form1};
值得注意的是,该函数或过程应加入窗体的Create和Free(产生和释放)方法。
(4)对项目进行编译即形成DLL文件,可被其它项目调用。
二、Delphi中DLL的调用
调用DLL有两种方法,一种是在应用程序装载时调用,另一种是在应用程序运行时调用。
(1) 装载时调用DLL
在调用DLL的Pas文件中,对DLL函数进行外部声明,声明应位于Implementation后,形式如下:
Implementation
Function functionname(argment):Boolean;far;External 'DllName';
其中External关键字后面的引号内是DLL的文件名,该文件一般应放在系统的system目录下,或与调用它的项目同一目录。声明以后即可在Pas文件任何地方引用DLL函数。
装载时调用DLL的优点是速度较快,程序间也可共享代码。
(2) 运行时调用DLL
DLL的另一种调用方法是在运行时调用。这种方法要调用到Windows的API函数LoadLibrary,GetProcAddress,FreeLibrary等。此方法主要用于调用其它语言,特别是C++编译的DLL。
假定你欲调用的DLL中包括一个函数:
Function checkpwd(pwd:string):boolean;export;
那么,首先在欲调用DLL的程序Type类型声明处加入一句:
Type
Tcheckpwd= function(pwd:string):boolean;
此句的作用如同C++中声明的函数指针。
然后定义如下变量∶
Var
aptr:TFarproc;
lhnd:THandle;
flag:boolean;
其中Aptr,lhnd两变量声明必须有,flag是DLL函数返回值,视情况而定。在调用DLL处加入如下语句进行DLL装载:
lhnd:=Loadlibrary('路径:DLL文件名');{如lhnd:=Loadlibrary('c:\project1.dll');
aptr:=GetprocAddress(lhnd,'checkpwd');
下面可直接调用DLL了:
flag:=Tcheckpwd(aptr)( 'pwd');{根据函数填相应的变量参数}
调用完以后,用FreeLibrary释放DLL占用的内存:
FreeLibrary(lhnd);
三、用VC创建DLL
在VC中创建DLL,与Delphi中的创建过程相似,步骤如下:
(1)新建一个DLL项目。MFC提供两种类型的动态链接库:常规型DLL、扩展型DLL。其中,常规型DLL适合于非MFC开发环境下采用支持DLL调用的程序设计语言开发的应用程序,扩展型DLL只能被MFC程序使用。
(2)创建该DLL中的过程或函数,只需在程序中加入下列语句:
extern "C" _declspec(dllexport)
int yanzheng(CString input,char* zcm)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
file://具体实现过程
}
该函数的功能是验证注册码是否合法,其中yanzheng为函数名,int为函数返回值类型,()内为函数参数。编译通过后即可使用。
四、 VC中DLL的调用
在VC中调用动态链接库时,类似于Delphi中运行时调用DLL的方法。也要调用到Windows的API函数LoadLibrary,GetProcAddress等。此方法对于调用其它语言和VC编译的DLL均适用。
假定DLL中包括一个函数:
int yanzheng(CString input,char* zcm)
首先在欲调用DLL函数的cpp文件前部先声明函数指针,定义函数类型:
typedef int (* _YANZHENG)(CString,char* zcm);
然后定义如下变量∶
HINSTANCE hLibrary;
_YANZHENG yanzheng;
在调用DLL处加入如下语句进行DLL装载:
hLibrary=LoadLibrary("zcdll.dll");
yanzheng=(_YANZHENG)GetProcAddress(hLibrary,"yanzheng");
shuchu= (*yanzheng)(shuru,zcm);
FreeLibrary(hLibrary);
五、 几点提示
(1)如果用Delphi创建DLL时用到其它的form,则在DLL的输出函数中应包括form的create(创建)和free(释放),而且在显示该窗口时只能用showmodal过程,不能用show过程,在后面的例子中能详细看到。
(2)如果Delphi创建的DLL中的函数或过程,用string类型作为参数输入或返回string类型,当用VC或其它程序调用时,经常会出错,反之亦然。为了解决这种情况,使不同程序之间在使用字符串类型时,接口更安全,建议使用pchar类型,而不是string类型。而且要在程序中加入内存管理,使用系统提供的sharemem单元。下面是一个实现将星期标识由数字转换成英文的例子:
uses
sharemem;
exports
makeitaday;
var
mydate:pchar;
function makeitaday(S:integer):pchar;stdcall;export;
implementation
function makeitaday(S:integer):pchar;stdcall;export;
var
thedate:array[0..20] of char;
begin
GetMem(mydate, 200);
if s=1 then thedate:='Sunday ';
file://……….
strpcopy(mydate,thedate);
makeitaday:=mydate;
end;
六、实例
因为用Delphi创建和调用DLL,过程与用VC创建和调用DLL相似,只是前者代码要比在VC环境中稍微复杂一些,因此在文章的最后给出一个完整的用Delphi创建和调用DLL的例子。该DLL主要用来检查输入的口令是否正确,窗体含有一个Edit编辑框,一个按钮Button,在编辑框内输入口令,比较编辑框的值和输入参数返回真假值。
//文件名为checkpassword.dpr;编译此文件生成checkpassword.dll
library checkpassword;
uses
SysUtils, Classes, Unit1 in 'Unit1.pas' {Form1};
exports
checkpwd name 'checkpwd';//声明DLL函数
{$R *.RES}
begin
end.
file://文件名为unit1.pas
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
password: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
flag:boolean;//返回输入密码是否正确
rightpwd:string;//记录输入参数(正确的密码)
function checkpwd(pwd:string):boolean;export;//声明DLL函数
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
if password.text=rightpwd then
flag:=true;
form1.close;
end;
function checkpwd(pwd:string):boolean;export;
begin
flag:=false;
rightpwd:=pwd;//读入正确的密码值
form1:=Tform1.create(Application);//创建密码验证窗口
form1.ShowModal;//显示窗口
checkpwd:=flag;
form1.free;//释放资源
end;
end.
file://主程序main.pas,调用DLL
unit main;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;
type
TForm1 = class(TForm)
jieguo: TEdit;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
function checkpwd(pwd:string):boolean;external 'project1.dll' ;//函数说明
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject);
begin
if checkpwd('congrong') then//调用函数
jieguo.text:='true'
else
jieguo.text:='false';
end;
end.
以上程序在Windows98/Delphi5下编译通过。
C# Csharp
调用
C++
的
DLL
中的
回调函数
一个是
C++
的
DLL
以及源码 一个是
调用
他的C#源码 都是VS2010编译测试通过
C#
调用
C++
的
dll
实例,
回调函数
,string和int数组参数传递
C#
调用
C++
的
dll
实例,
回调函数
,string和int数组参数传递,在vs2010下调试通过,总结在这里,供大家参考。
QT编写
DLL
调用
示例 方法 参数 返回值 事件回调
QT编写
DLL
给外部程序
调用
示例 方法 参数 返回值 事件回调 : 1:C#或者 NET 第一步:引入命名空间; using System Runtime InteropServices; 第二步:声明函数 必须与实际
DLL
中函数名及参数一致; [
Dll
Import "qt
dll
dll
" ] public static extern int add int i ; 第三步:
调用
函数执行; Console WriteLine add 10 ToString ; 2:QT 第一步:引入头文件; #include <QLibrary> 第二步:定义函数指针 以备
调用
; typedef int Add int ; 第三步:载入
DLL
调用
函数执行; QLibrary lib "qt
dll
dll
" ; lib load ; Add add Add lib resolve "add" ; add 50 ; 3:C或
C++
第一步:引入头文件; #include <windows h> 第二步:定义函数指针; typedef int Add int ; 第三步:载入
DLL
调用
函数执行; HINSTANCE h
Dll
LoadLibrary "qt
dll
dll
" ; 载入
DLL
获取句柄 if h
Dll
NULL { Add add Add GetProcAddress h
Dll
"add" ; 获取函数地址 printf "%d" add 110 ; FreeLibrary h
Dll
; 释放
DLL
}">QT编写
DLL
给外部程序
调用
示例 方法 参数 返回值 事件回调 : 1:C#或者 NET 第一步:引入命名空间; using System Runtime InteropServices; 第二步:声明函数 必须与实际
DLL
中函数名及参数一致; [
Dll
Import "qt
dll
dll
" ] public static extern int add in [更多]
C#
调用
c++
工程文件(调试已通过)
C#
调用
c++
工程文件C#
调用
c++
工程文件C#
调用
c++
工程文件C#
调用
c++
工程文件C#
调用
c++
工程文件C#
调用
c++
工程文件C#
调用
c++
工程文件C#
调用
c++
工程文件
java用JNA
调用
dll
实例,包含各种参数
调用
实例中演示了各种参数形式的
DLL
函数
调用
,如:基本数据类型、基本数据类型的指针和引用、结构体、结构体的指针和引用、函数指针和
回调函数
、字符串指针、输入数组、输出数组等,非常实用。
Delphi
5,939
社区成员
262,944
社区内容
发帖
与我相关
我的任务
Delphi
Delphi 开发及应用
复制链接
扫一扫
分享
社区描述
Delphi 开发及应用
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章