为什么这个过程不是TProc?

4

我有以下类似的情况:

interface

type
    IMyInterface = interface
    [GUID]
        procedure MyProcedure; stdcall;
    end;

    TMyOBject = class(TInterfacedObject, IMyInterface)
        procedure MyProcedure; virtual; stdcall; abstract;
    end;

    TDerivedObject = class(TMyOBject)
        procedure MyProcedure; override; stdcall;
        procedure SomeOtherProcedure;
    end;

implementation

uses
    System.Threading;

procedure TDerivedObject.MyProcedure;
begin
    //DoStuff;
end;

procedure TDerivedObject.SomeOtherProcedure;
begin
    TTask.Run(MyProcedure); //Error: Run can't be called with this parameter
end;

编译器说我不能使用TTask来运行MyProcedure。将MyProcedure强制转换为TProc是错误的。我的问题是:1)MyProcedure是什么类型?2)我该如何发现MyProcedure的类型?
谢谢
1个回答

6

TProc不使用stdcall调用约定。它被声明为一种匿名方法类型,使用默认的register调用约定:

 TProc = reference to procedure;

相比之下

 TMyProcedure = procedure of object; stdcall;

匿名方法与声明调用约定不同于标准Delphi register约定的方法不兼容。要么不使用stdcall,要么插入包装器方法或本地匿名方法,例如:

procedure TDerivedObject.SomeOtherProcedure;
begin
  TTask.Run(procedure begin MyProcedure; end); 
end;

@J 谢谢。你说的30个字符是什么意思? - David U
@J 好的,但我可以在TDerivedObject中创建另一个方法,命名为'LocalProc',从LocalProc运行MyProcedure,并成功地将LocalProc传递给TTask.Run。在我看来,LocalProc是一个“对象过程”,而不是TProc,但它可以工作。 - David U
@DavidU 是的,但通常情况下,对象过程与匿名的过程引用类型是赋值兼容的(通过编译器魔法),只要没有调用约定覆盖。如果您对此有更多细节(和一些注意事项)感兴趣,请参见此问题 - J...
@DavidU 话虽如此,对于没有参数的void方法,registerstdcall约定之间没有区别 - 我猜这是为将要插入外部API的某些内容而编写的样板代码,其中将有参数和返回值?如果不是,显然的解决方案就是不要用stdcall修饰你的类方法。 - J...
@J 是的,如果我理解您的问题。我正在执行Facebook登录,这会给我一个短期令牌。我想尝试在后台将短期令牌换成长期令牌。我还不知道它是否有效。 - David U

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接