Delphi 当从不同的模块传递实例时,为什么is运算符无法返回我期望的结果?
我从事Delphi项目,与许多其他小型库进行交互。 我使用FastMM4,我想处理通过dll参数传递的复杂类 例如,我将表单发送到我的dll。在dll中,我使用运算符“IS”测试参数的类型 但在Dll中,运算符“IS”始终返回“false” 例Delphi 当从不同的模块传递实例时,为什么is运算符无法返回我期望的结果?,delphi,dll,fastmm,Delphi,Dll,Fastmm,我从事Delphi项目,与许多其他小型库进行交互。 我使用FastMM4,我想处理通过dll参数传递的复杂类 例如,我将表单发送到我的dll。在dll中,我使用运算符“IS”测试参数的类型 但在Dll中,运算符“IS”始终返回“false” 例 library Dll; uses FastMM4, System.SysUtils, System.Classes, Vcl.Dialogs, Vcl.Forms; {$R *.res} proc
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
是不同的类。这就是为什么的计算结果为假
处理此问题的传统方法是安排流程中只有一个RTL/VCL实例。您可以通过使用运行时包来实现这一点
如果运行时包对您来说不是一个可行的选项,并且您必须使用DLL,那么您将不得不放弃跨DLL边界传递任何Delphi类。我完全认为这是不受欢迎的消息,但事实就是这样。您不能跨DLL边界传递TObject
实例并尝试调用DLL不支持的方法、查询类型标识等。仅适用于运行时包
因此,如果您必须使用DLL,那么您需要坚持使用简单类型。整数、浮点值、字符类型、数组(但不是动态数组)、记录、指向此类类型的指针、接口。作为一个简单的经验法则,如果您在Win32中找不到建议的互操作示例,那么它可能是无效的 首先,您的呼叫约定不匹配。您必须通过使互操作边界两侧的调用约定相同来解决这个问题
即使在您修复该问题时,is
运算符的明显错误行为也是意料之中的。您的流程中有两个VCL实例。一个在主机中,一个在DLL中。它们都有VCL中定义的类的不同版本。因此,DLL的TForm
与主机中的TForm
是不同的类。这就是为什么的计算结果为假
处理此问题的传统方法是安排流程中只有一个RTL/VCL实例。您可以通过使用运行时包来实现这一点
如果运行时包对您来说不是一个可行的选项,并且您必须使用DLL,那么您将不得不放弃跨DLL边界传递任何Delphi类。我完全认为这是不受欢迎的消息,但事实就是这样。您不能跨DLL边界传递TObject
实例并尝试调用DLL不支持的方法、查询类型标识等。仅适用于运行时包
因此,如果您必须使用DLL,那么您需要坚持使用简单类型。整数、浮点值、字符类型、数组(但不是动态数组)、记录、指向此类类型的指针、接口。作为一个简单的经验法则,如果您在Win32中找不到建议的互操作示例,那么它可能是无效的 注意呼叫约定。您的声明彼此不匹配。是的,当然我在上一次的示例中更改了reduce代码。抱歉,这真的是“Proc:procedure(l:TObject)”注意调用约定。您的声明彼此不匹配。是的,当然我在上一次的示例中更改了reduce代码。抱歉,这真的是“Proc:procedure(l:TObject)