gpt4 book ai didi

delphi - 在使用包编译的 dll 和不使用包编译的 dll 之间处理回调方法是否安全(Delphi)?

转载 作者:行者123 更新时间:2023-12-03 15:45:25 32 4
gpt4 key购买 nike

我使用的是 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 的文档中没有找到任何可能可以澄清这些问题的内容。

最佳答案

你的代码没问题。当您传递方法指针 TFooBar 时,您将传递两个指针:一个函数指针和一个实例指针。当您调用该方法时,所有版本的 Delphi 都会执行完全相同的操作来调用该方法,因为调用约定强制执行精确的二进制接口(interface)。所有版本的 Delphi 都以相同的方式表示方法指针。

您关心的问题是:

  1. 不同的内存管理器。这里没问题,因为我们不进行堆分配。
  2. 不同编译器上的不同对象表示。这里没有问题,因为调用方法指针不依赖于对象表示。它依赖于代码指针和数据指针(模块之间按值传递)以及调用约定(约定一致)。

关于delphi - 在使用包编译的 dll 和不使用包编译的 dll 之间处理回调方法是否安全(Delphi)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10275773/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com