为什么操作符无法返回从其他模块传递实例时的预期?

Joc*_*c02 1 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}

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.
Run Code Online (Sandbox Code Playgroud)

和电话

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;
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 6

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

即使你解决了这个问题,is也可以预期运营商的明显不当行为.您的流程中有两个VCL实例.一个在主机中,一个在DLL中.它们各自具有VCL中定义的类的不同版本.因此,DLL TFormTForm主机中不同的类.这就是is评估错误的原因.

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

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

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