Когда у вас есть объект, который реализует несколько интерфейсов, и вы преобразуете между ними, вы получите разные адреса. Это связано с тем, как найти методы этих интерфейсов.
Допустим, у вас есть два интерфейса и класс, который их реализует, методы показывают только сообщение с именем метода:
type
IMyIntfA = interface
['{21ADE2EF-55BB-4B78-A23F-9BB92BE55683}']
procedure A;
procedure X;
end;
IMyIntfB = interface
['{7E1B90CF-569B-4DD1-8E46-7E7255D2373A}']
procedure B;
end;
TMyObject = class(TInterfacedObject, IMyIntfA, IMyIntfB, IUnknown)
public
procedure A;
procedure X;
procedure B;
end;
Когда вы говорите компилятору вызывать A из IMyIntfA, он знает, что A находится по адресу IMyIntfA плюс смещение. То же самое относится и к вызову метода B из IMyIntfB.
Но вы делаете, что помещаете ссылку на IMyIntfB в переменную IMyIntfA, а затем вызываете метод A. В результате адрес метода, который вычисляет компилятор, совершенно неверен.
var
lIntfA: IMyInterfaceA;
lIntfB: IMyInterfaceB;
begin
lIntfA := TMyObject.Create; //TMyObject implements IMyInterfA, IMyInterfB
lInfB := lIntfA as IMyInterfaceB;
if Integer(lIntfA) <> Integer(lIntfB) then
ShowMessage('I told you so');
Pointer(lIntfA) := Pointer(lIntfB);
lIntfA.A; //procedure B is called, because B is at "Offset 1", like A
lIntfA.X; //total mayhem, X is at "Offset 2", but there is nothing at IMyIntfB + offset 2
end;
PS: Я не гуру, и я не знаю технических деталей о том, как все реализовано. Это только грубое объяснение, которое должно дать вам представление о том, почему ваш код работает неправильно. Если вы хотите, чтобы ваш код был успешным, сделайте это:
Vis := Interface_ as IVApplication;
Str := (Vis.Path);