gpt4 book ai didi

delphi - 带参数和结果的回调

转载 作者:行者123 更新时间:2023-12-02 10:57:25 24 4
gpt4 key购买 nike

我尝试了很长时间来寻找这个问题的答案,但没有找到任何东西。我正在尝试将带有数据的回调传递给函数。

这是我的伪代码:

TGetFreeNumber = function(data: Pointer): integer;


procedure TMyClass.AddToDatabase(cb: TGetFreeNumber{???});
var
num: integer;
begin
num := {{Invoke cb with parameters}};
// INSERT INTO ... VALUES num ...
end;


procedure TMyClass.impl1(from, till: integer);

function myCB(data: Pointer);
begin
result := 123;
end;

begin
AddToDatabase(@myCB(someData){???});
end;


procedure TMyClass.impl2(from, till: integer);

function myCB(data: Pointer);
begin
result := 456;
end;

begin
AddToDatabase(@myCB(someData){???});
end;

我用 TMethod 做了一些实验,但没有找到像这样的合适的 Invoke 方法

procedure TMyClass.AddToDatabase(cb: TMethod);
var
num: integer;
begin
num := Invoke(cb.Code, cb.Data);
// INSERT INTO ... VALUES num ...
end;

最佳答案

您需要进行两项更改。您的 AddToDatabase 方法需要接受回调的参数以及回调方法本身。这是必需的,以便在调用回调时可以将它们传递给回调。

procedure TMyClass.AddToDatabase(cb: TGetFreeNumber; data: Pointer);
var
num: integer;
begin
num := cb(data);
// INSERT INTO ... VALUES num ...
end;

并且您也不得在回调中使用嵌套函数。引用嵌套函数是违反语言规则的。 documentation 说:

Nested procedures and functions (routines declared within other routines) cannot be used as procedural values.

所以你应该像这样编写代码:

function myCB(data: Pointer);
begin
result := 456;
end;

procedure TMyClass.impl2(from, till: integer);
begin
AddToDatabase(myCB, someData);
end;

另请注意,我在传递回调时删除了 @ 的使用。删除 @ 允许编译器检查回调是否满足要求。在您的代码中它没有,因为它是一个嵌套函数。您使用 @ 产生了一个无类型指针,因此逃避了类型检查。

由于历史的怪癖,如果您使用 @ 运算符抑制类型检查,32 位 Windows 编译器将允许您使用嵌套函数作为过程变量。此外,只要嵌套函数不引用其外部作用域中的任何内容或 Self 中包含的任何内容,对该过程变量的调用就可以工作。但我认为不应依赖这种行为。

如果您需要回调来访问实例的方法,请将其设为方法类型:

type
TGetFreeNumber = function(data: Pointer): integer of object;

并传递你的类的方法。

或者,如果您更愿意使用匿名方法和变量捕获,并且您的 Delphi 版本支持它们,则使用引用函数:

type
TGetFreeNumber = reference to function(data: Pointer): integer;

关于delphi - 带参数和结果的回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34874603/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com