我有一个很大的问题,因为我不明白指针在delphi中是如何工作的
首先我从dll中获取一个函数声明。
功能:
type
TMICRCallback = function: Integer; stdcall;
然后我在我的代码中声明了一个函数。
function CBMICRRead : Integer;stdcall;
功能非常简单(这是一个例子)
function TCustomizedTenderPlugin.CBMICRRead : Integer; stdcall;
var
SUCCESS:integer;
begin
SUCCESS:=1;
Result:= SUCCESS;
end;
我宣布像这样的变种
Respuesta : TMICRCallback;
当我尝试将此变量分配给我的函数时,问题就出现了:(
Respuesta := CBMICRRead;
这是我第一次在delphi中使用指针,所以可能是一个愚蠢的问题,但请帮助我
答案 0 :(得分:6)
TCustomizedTenderPlugin.CBMICRRead
是一个实例方法。这意味着为了调用它,你必须有一个实例来调用它。
另一方面,TMICRCallback
是函数指针。它与普通函数兼容,而不是实例方法。
它们根本不兼容。要使TCustomizedTenderPlugin.CBMICRRead
与TMICRCallback
兼容,您需要将其定义为:
TMICRCallback = function: Integer of object; stdcall;
of object
表示此类型与实例方法兼容。类型TMICRCallback
的变量(在本回答中定义)包含函数指针和实例指针。它有时被称为双指针函数类型。
在继续之前,我建议您仔细阅读documentation。
我注意到您正在为这些函数指针使用stdcall
调用约定。这通常表示您正在尝试与外部模块互操作。这不是实例方法可靠的东西。我的意思是你不能用Delphi以外的语言实现of object
实例方法。如果此代码注定要在互操作设置中使用,那么您应该避免使用of object
。
对于互操作设置,通常会将实例指针包含为单独的参数。在这种情况下,Delphi声明将如下所示:
type
TMICRCallback = function(Data: Pointer): Integer; stdcall;
然后你会实现像这样的函数
type
TPlugin = class
function CBMICRRead: Integer;
end;
.....
function PluginCBMICRReadCallback(Data: Instance): Integer; stdcall;
begin
Result := TPlugin(Data).CBMICRRead;
end;
function TPlugin.CBMICRRead: Integer;
begin
Result := ....
end;
最后,传递回调的外部模块中的函数需要传递PluginCBMICRReadCallback
和TPlugin
实例的实例指针。也许有点像这样:
procedure RegisterCallback(Callback: TMICRCallback; Data: Pointer); stdcall;
你会这样称呼:
var
Plugin: TPlugin;
....
Plugin := ...;//get this instance from somewhere
RegisterCallback(PluginCBMICRReadCallback, Plugin);
看了related question处的C ++代码,看起来接口的C ++端看起来像这样:
int WINAPI BiMICRSetReadBackFunction(int nHandle,
int (CALLBACK *pMicrCB)(void),
LPBYTE pReadBuffSize,
LPBYTE readCharBuff,
LPBYTE pStatus,
LPBYTE pDetail);
此回调甚至不允许数据指针,因此您根本无法使用实例方法。你是多么意想着为多个实例实现回调超出我的意义!无论如何,你可以像这样在Delphi中声明这个函数:
type
TMICRCallback = function: Integer; stdcall;
function BiMICRSetReadBackFunction(
nHandle: Integer;
MicrCB: TMICRCallback;
pReadBuffSize: PByte;
readCharBuff: PByte;
pStatus: PByte;
pDetail: PByte
): Integer; stdcall; external dllname;
要打电话给你,你需要这个:
function MICRCallback: Integer; stdcall;//not the method of a class
begin
Result := ....
end;
.....
retval := BiMICRSetReadBackFunction(..., MICRCallback, ....);
答案 1 :(得分:0)
显然CBMICRRead
被定义为对象方法(即TCustomizedTenderPlugin
的方法),因此不是'独立'函数。因此,你需要做
type
TMICRCallback = function: Integer of object; stdcall;
答案 2 :(得分:0)
如果DLL中的函数声明不是您编写的对象方法,则可以通过将该函数声明为全局函数而不是对象的方法来解决此问题,或者可以将其声明为静态类对象的功能。
class function CBMICRRead: Integer; static; stdcall;