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