Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 10.2 Tokyo-接口提供的Casting对象_Delphi_Interface_Delphi 10.2 Tokyo - Fatal编程技术网

Delphi 10.2 Tokyo-接口提供的Casting对象

Delphi 10.2 Tokyo-接口提供的Casting对象,delphi,interface,delphi-10.2-tokyo,Delphi,Interface,Delphi 10.2 Tokyo,我正在尝试将我的应用程序从Delphi XE8转换为10.2 Tokyo。我得到了由Interface acrocss包(bpl)提供的转换对象的奇怪运行时示例。当我试图用“as”关键字投射对象时,我得到 运行时发生此异常: Project 1.exe引发异常类EInvalidCast,并显示消息 “无效的类类型转换” 代码如下: separte软件包Plugin_Interface.bpl中的接口: unit MainIntf; interface Type IMainInft = in

我正在尝试将我的应用程序从Delphi XE8转换为10.2 Tokyo。我得到了由Interface acrocss包(bpl)提供的转换对象的奇怪运行时示例。当我试图用“as”关键字投射对象时,我得到 运行时发生此异常:

Project 1.exe引发异常类EInvalidCast,并显示消息 “无效的类类型转换”

代码如下:

separte软件包Plugin_Interface.bpl中的接口:

unit MainIntf;

interface
  Type IMainInft = interface
  ['{FE08C4A2-069C-4B8C-BB1B-445348CAB6A0}']
    function GetForm : TObject;
  end;

implementation

end.
Project1.exe中提供的接口实现:

unit MainImpl;

interface
uses MainIntf;

  Type TMain = class(TInterfacedObject,IInterface,IMainInft)
    function GetForm : TObject;
end;


implementation
uses unit1;

function TMain.GetForm: TObject ;
begin
  result:=Form1; // interafce is implemented on the main form so Form1 is rechable form here
end;


end.
最后,在另一个包“plugin.bpl”中,我试图从接口获取对象:

unit Plugin_main;

interface
uses Mainintf, Vcl.Forms;

type TPlugin = class (Tobject)
  IIMyRefernceToMianIntf: IMainInft;
end;

function RegisterPlugin(AMainIntf: IMainInft): TForm ; export;
procedure UnRegisterPlugin; export;

exports
  RegisterPlugin,
  UnRegisterPlugin;

var
 Plugin_obj:  TPlugin;

implementation
uses vcl.Dialogs,System.Classes ;

function RegisterPlugin(AMainIntf: IMainInft): TForm ;
var
 MyForm : TForm ;
begin
  Plugin_obj:=TPlugin.Create;
  Plugin_obj.IIMyRefernceToMianIntf:=AMainIntf;

  if AMainIntf.GetForm is TForm then
    Showmessage ('Great it is a Tform') // will not happen
  else
    Showmessage ('Sorry  it is not Tform'); // will happen 
  if TComponent (AMainIntf.GetForm).Classname='TForm1' then
    Showmessage ('What ?? It is TForm1 decsendant from TForm  so is it TForm after all ?!');  // will happen 
// result:=  AMainIntf.GetForm as TForm  -- This will rise na exception
  result:= TForm( AMainIntf.GetForm)  ; // this will work

end;

procedure UnRegisterPlugin;
begin
  Plugin_obj.Free;
end;
end.
为什么我不能使用“as”和“is”关键字。 只有硬猫叫才行,但我讨厌这样做。 在XE8编译器上,一切都按预期工作-XE 10.2 tokyo编译器上存在问题

关键字“is”检查实际对象,以查看它是否属于您要求的类型。那么,检查一下这个:

if AMainIntf.GetForm is TForm then
Showmessage ('Great it is a Tform') // will not happen
不会发生,因为
GetForm
返回
TObject
而不是
TForm
。使用“is”进行检查也意味着您正在检查可铸造性,即使用“as”关键字的能力。由于“is”检查失败,该命令也会失败:

result:=  AMainIntf.GetForm as TForm;
您的下一个选择是以您的方式强制转换GetForm:

TForm(AMainIntf.GetForm);
这是因为此转换不会检查
GetForm
是否为
TForm
类型。由于您在
TMain
中返回了一个表单,因此此硬选对您来说是安全的


话虽如此,为什么不直接返回
TForm
,而不是
TObject
?您是否在返回除
TForm
以外的其他类型的其他类中使用
IMainInft

您的项目是否启用了运行时包?这种错误通常意味着RTL/VCL库的单个实例没有在可执行文件之间共享,导致每个可执行文件中的RTTI不同。感谢Remy,就是这样,该选项已在XE10.2中移动,现在在名为“runtime packages”的separte选项页上被称为“与运行时包链接”@jackDph:没有xe10.2。这是Delphi或RAD Studio 10.2,看不到XE。XE行在XE8处停止。@RemyLebeau,你真的应该把它变成一个答案,或者-最好-找到重复的并关闭它。只要左边的对象在其类层次结构中的某个地方有
TForm
,那么
as
操作符就可以工作。这里的问题(如Remy在上面的评论中所述)是BPL没有与可执行文件共享类型数据,因此使用了不同的
TForm