我正在使用Delphi 2007,我有这个案例:
{ CommonUnit.pas }
type
// there is a callback which I want to process
TFooBar = procedure(Sender: IInterface) of object; stdcall;
// there is an interface which is used by all modules
IFoo = interface
['{0FAA4B2B-E82A-4A2A-B55F-C75EC53A1318}']
procedure Bar(Callback: TFooBar); stdcall;
end;
{ UnitInModuleCompiledWithoutPackages.pas }
type
// there is a class which implements IFoo
// and it's defined in Module One compiled without packages
TFoo = class(TInterfacedObject, IFoo)
public
// implementation is ommited
procedure Bar(Callback: TFooBar); stdcall;
end;
{ UnitInModuleCompiledWithPackages.pas }
// there is a code in Module Two compiled with packages
type
TSomeClass = class
public
// implementation is ommited
procedure SomeMethod(Sender: IInterface); stdcall;
end;
var
SomeObject: TSomeClass; // assigned by somehow
Foo: IFoo; // assigned by somehow
begin
// ...
Foo.Bar(SomeObject.SomeMethod); // so it is safe?
// ...
end;
我知道如果我在Foo.Bar
中尝试传递对象引用,如果它被声明为这样,那么在我的情况下会出现内存损坏:
type
IFoo = interface
['{0FAA4B2B-E82A-4A2A-B55F-C75EC53A1318}']
// TSomeClass now declared in CommonUnit.pas
procedure Bar(CallbackObject: TSomeClass); stdcall;
end;
这是因为模块一中的TSomeClass
的实现与模块二(不同的内存管理器等)的实现不同。
但是方法参考呢?
我没有在Embarcadero的文档中找到任何可能用来清理这些内容的东西。
答案 0 :(得分:5)
你的代码很好。当你传递方法指针TFooBar时,你传递两个指针,一个函数指针和一个实例指针。当您调用该方法时,所有版本的Delphi都会执行完全相同的操作来调用该方法,因为调用约定强制执行精确的二进制接口。并且所有版本的Delphi都以相同的方式表示方法指针。
您关心的问题是:
答案 1 :(得分:3)
正如David Heffernan已经回答的那样,使用方法指针很好。使用任何类型的“回调对象”而不是方法指针的唯一原因是: