You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 10.3.2 OSX64下修改QueryInterface调用约定的编译错误问题

解决Delphi 10.3.2 OSX64下自定义接口的调用约定与编译错误问题

我来帮你拆解这个问题,核心是Delphi对COM接口(尤其是IUnknown/IInterface)的特殊处理,以及跨平台调用约定的匹配问题。

为什么会出现E2211错误?

你遇到的编译错误,本质是因为你的MyIInterface使用了IUnknown的标准GUID({00000000-0000-0000-C000-000000000046})。Delphi会通过GUID识别接口类型,一旦匹配IUnknown的GUID,就会把你的自定义接口当作系统内置IInterface的等价物,强制要求你实现的方法和IInterface声明的调用约定完全一致。

而你尝试去掉stdcall/cdecl改用默认约定,就和系统IInterface中平台相关的调用约定(OSX下默认是cdecl)产生了冲突,于是抛出声明不一致的错误。

至于重命名QueryInterface为QueryInterface2仍要求实现原方法,也是同样的原因:Delphi认的是GUID,不是方法名——只要GUID是IUnknown的,就必须实现QueryInterface、_AddRef、_Release这三个标准方法。

解决方案

根据你的需求(对接GCC编译的dylib,使用OSX64默认调用约定),这里有两种可行的方案:

方案1:使用自定义GUID避免接口冲突

这是最安全的做法,彻底和系统IInterface解绑,自由定义调用约定:

  • 给你的自定义接口生成一个唯一的GUID(用Delphi菜单栏的Tools -> Create GUID生成)
  • 去掉所有调用约定修饰,使用OSX64默认约定

示例代码:

type
  // 替换成你自己生成的唯一GUID
  MyIInterface = interface ['{12345678-1234-1234-1234-123456789ABC}']
    function QueryInterface(const IID: TGUID; out Obj): HResult; // 默认调用约定
    function _AddRef: Integer;
    function _Release: Integer;
  end;

  TMyInterfacedObject = class(TObject, MyIInterface)
  protected
    function QueryInterface(const IID: TGUID; out Obj): HResult;
    function _AddRef: Integer;
    function _Release: Integer;
  end;

这样Delphi不会再把它和系统IInterface关联,你可以完全按照GCC dylib的要求定义调用约定,编译错误也会消失。

方案2:必须使用IUnknown GUID时的处理

如果你的dylib接口基于COM标准,必须用IUnknown的GUID,那需要修改系统IInterface的调用约定声明(仅限OSX64平台):

{$IFDEF OSX64}
  // 重新声明IInterface,替换默认调用约定
  type
    IInterface = interface
      ['{00000000-0000-0000-C000-000000000046}']
      function QueryInterface(const IID: TGUID; out Obj): HResult;
      function _AddRef: Integer;
      function _Release: Integer;
    end;
{$ENDIF}

TMyInterfacedObject = class(TObject, IInterface)
protected
  function QueryInterface(const IID: TGUID; out Obj): HResult;
  function _AddRef: Integer;
  function _Release: Integer;
end;

⚠️ 注意:这种方法会修改Delphi内置接口的行为,可能影响其他依赖IInterface的代码,一定要在OSX64条件编译下使用,并充分测试。

额外提示:匹配GCC的调用约定

OSX64下GCC默认使用System V AMD64 ABI调用约定,Delphi 10.3.2支持sysv关键字来显式指定这个约定。如果不确定默认约定是否匹配,你可以直接在方法上标注sysv:

type
  MyIInterface = interface ['{12345678-1234-1234-1234-123456789ABC}']
    function QueryInterface(const IID: TGUID; out Obj): HResult; sysv;
    function _AddRef: Integer; sysv;
    function _Release: Integer; sysv;
  end;

内容的提问来源于stack exchange,提问作者Ivan Petrovic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:23:06