gpt4 book ai didi

delphi - 为什么 is 运算符在从不同模块传递实例时无法返回我期望的结果?

转载 作者:行者123 更新时间:2023-12-03 19:07:53 24 4
gpt4 key购买 nike

我从事与许多其他小型库交互的 Delphi 项目。
我使用 FastMM4,我想处理通过 dll 参数传递的复杂类。

例如,我将表单发送到我的 dll。在 dll 中,我使用运算符“IS”测试参数的类型。

但是进入 Dll 的操作符“IS”总是返回“false”

示例

library Dll;

uses
FastMM4,
System.SysUtils,
System.Classes,
Vcl.Dialogs,
Vcl.Forms;

{$R *.res}

procedure Complex(L : TObject);stdcall;
begin
if L is TForm then
showmessage('Ok')
else
showmessage('Pas ok') ;

if L is TCustomFrame then
showmessage('Ok')
else
showmessage('Pas ok')
end;

exports
Complex;

begin
end.

和电话
procedure TffsIsOperator.Button2Click(Sender: TObject);
var
MaDLL : THandle;
Proc : procedure (l : TObject);
begin
try
MaDLL := LoadLibrary(PChar('Dll.dll'));
@Proc := GetProcAddress(MaDLL, 'Complex');
Proc(self);
finally
FreeLibrary(MaDLL);
end;
end;

最佳答案

首先,你有一个调用约定不匹配。您必须通过使互操作边界两侧的调用约定相同来解决此问题。

即使您解决了这个问题,is 的明显不当行为运营商是可以预期的。您的流程中有两个 VCL 实例。一个在主机中,一个在 DLL 中。它们每个都有 VCL 中定义的类的不同版本。所以,DLL 的 TForm是与 TForm 不同的类在主机。这就是为什么is评估为假。

处理此问题的传统方法是安排您的流程中只有一个 RTL/VCL 实例。您可以通过使用运行时包来实现这一点。

如果运行时包对您来说不是一个可行的选择,并且您必须使用 DLL,那么您将不得不放弃通过 DLL 边界传递任何 Delphi 类。我完全认为这是不受欢迎的消息,但事实就是如此。你不能通过 TObject跨 DLL 边界的实例并尝试调用方法、查询类型标识等。DLL 根本不支持。仅适用于运行时包。

因此,如果您必须使用 DLL,那么您需要坚持使用简单类型。整数、浮点值、字符类型、数组(但不是动态数组)、记录、指向此类类型的指针、接口(interface)。作为一个简单的经验法则,如果您在 Win32 中找不到建议的互操作示例,那么它可能是无效的。

关于delphi - 为什么 is 运算符在从不同模块传递实例时无法返回我期望的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24144817/

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