在 Delphi 2010 RIDL 编辑器中定义类型 function/procedure 指针的 属性

Defining property of type function/procedure pointer in Delphi 2010 RIDL editor

我想知道是否可以在 Delphi 2010 RIDL 编辑器中为接口定义定义 属性 类型 function/procedure 指针,这样当我创建一个实例时它的实现者使用它的 CoCreator,然后我可以在我的源代码中分配一个使用该接口定义的 function/procedure 到那个 属性。其实我想知道如何在下面填写“???”。

TLB 文件:

IComIntf = interface(IDispatch)
...
  function Get_OnDoSomething : ??? safecall;
  procedure Set_OnDoSomething(const New_Event : ???); safecall;
...
  property OnDoSomething : ???;
...
implementation

uses ComObj;

class function CoComIntf.Create: IComInt;
...
begin
  Result := CreateComObject(CLASS_ComIntf) as IComIntf;
end;

实现文件,ComIntfUnit.pas:

type
  TOnDoSomething = function (Info: OleVariant): HResult of object;

TComIntf = class(TAutoObject, IComIntf)
private
  fOnDoSomething : TDoSomething;
...
public
  property OnDoSomething: TOnDoSomething read fOnDoSomething write fOnDoSomething;
...

客户表格:

uses ComIntfUnit;

type
  TForm1 = class(TForm)
  private
  { Private declarations }
    fCom : IComIntf;
    function DoSomething(Info: OleVariant): HResult;
  public
  { Public declarations }
...
  end;
...

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  fCom := CoComIntf.Create;
  fCom.OnDoSomething := DoSomething;
...

提前致谢。

原始函数指针不是 COM 兼容类型。如果愿意,您当然可以使用 void 指针,但这并不符合 COM 的精神。

你在这里要做的是传递另一个接口。然后被调用者可以调用该接口上的函数并执行调用者的代码。

你的做法是错误的。实现它的正确方法是定义客户端实现并传递给您的 COM 对象的第二个接口。然后 COM 对象可以保留该接口并在需要时调用它的方法。这通常使用 Connection Points 作为事件接口来实现。

一个简单的实现方法,特别是因为您正在使用 IDispatch,是使用 IDE 向导创建一个新的 Automation Object,并且请务必单击向导对话框中的 "Generate Event support code" 复选框。然后向导会生成2个接口,一个为对象本身,一个为对象的事件,并为你实现连接点逻辑。然后,您可以根据需要向 2 个接口添加方法,其中对象方法在需要时调用事件方法。

如果您随后编译、注册并将最终对象导入 IDE 并为其生成 VCL 包装器,生成的组件将具有内部连接到对象的连接点事件。