【问题标题】:Why is this procedure not a TProc?为什么这个过程不是 TProc?
【发布时间】:2019-10-04 02:41:27
【问题描述】:

我的情况如下:

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 的类型?

谢谢

【问题讨论】:

    标签: delphi


    【解决方案1】:

    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 个字符是什么意思?
    • @J 好的,但是我可以在 TDerivedObject 中创建另一个方法,将其命名为“LocalProc”,从 LocalProc 运行 MyProcedure,并成功将 LocalProc 传递给 TTask.Run。在我看来,LocalProc 是一个“对象过程”而不是 TProc,但它确实有效。
    • @DavidU 是的,但是只要不涉及调用约定覆盖,普通的procedure of object 通常与匿名reference to procedure 类型的赋值兼容(通过编译器魔法)。如果您对这一点(以及一些注意事项)感兴趣,请参阅this question
    • @DavidU 话虽如此,对于没有参数的 void 方法,registerstdcall 约定之间没有区别 - 我认为这是要插入的东西的样板会有参数和返回值的外部 API?如果没有,显而易见的解决方案就是不要用stdcall 装饰你的类方法。
    • @J 是的,如果我理解你的问题。我正在执行 Facebook 登录,这给了我一个短期令牌。我想我会尝试在后台将短期代币换成长期代币。我不知道它是否还有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2022-11-16
    • 1970-01-01
    • 2015-07-24
    相关资源
    最近更新 更多