I’m using Delphi 2007 and I have this case:
{ 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;
I know that it will be a memory corruption in my case when I would to try to pass an object reference in Foo.Bar if it’s declared like this:
type
IFoo = interface
['{0FAA4B2B-E82A-4A2A-B55F-C75EC53A1318}']
// TSomeClass now declared in CommonUnit.pas
procedure Bar(CallbackObject: TSomeClass); stdcall;
end;
That is because implementation of TSomeClass in Module One is not the same as in Module Two (different memory managers and so on).
But what about a method references?
I haven’t found anything in Embarcadero’s documentation that might be to clear up this things.
Your code is fine. When you pass around the method pointer TFooBar you are passing two pointers, a function pointer and an instance pointer. When you invoke that method, all versions of Delphi do the exact same thing to invoke the method because the calling convention enforces a precise binary interface. And all versions of Delphi represent a method pointer in the same way.
The problems that you are concerned about are: