Часть проблемы, заключающаяся в том, что в Delphi объекты могут реализовывать интерфейсы, но сами по себе они не являются интерфейсными объектами.
Чтобы понять это различие, вы должны взглянуть на грубую реализацию интерфейса
на объекте Delphi, и понять механизм подсчета ссылок, используемый COM. Еще одна вещь
следует понимать, что .NET не работает таким же образом, так что, похоже,
Интерфейс в .NET для объекта такой же, как представлен аспект ComVisible.
TYPE
TMyObject = class(TInterfacedObject, IMyObject, IMyNewInterface)
end;
Учитывая вышесказанное, об этом объекте можно сказать следующее.
Вы создали новый COM-объект с помощью мастера Delphi COM-объектов.
Интерфейс IMyObject определен как интерфейс по умолчанию, а TMyObject - конкретный класс
который будет реализовывать этот интерфейс.
IMyNewInterface - это дополнительный интерфейс, определенный где-то еще, который вы указали
объект реализует.
Вы можете сделать следующее с этим объектом
var
I1: IMyObject;
I2: IMyNewInterface;
T: TMyObject;
begin
I1:=TMyObject.Create;
I2:=TMyObject.Create;
T:=TMyObject.Create;
end;
Вы можете делать эти вещи, потому что TMyObject РЕАЛИЗУЕТ эти интерфейсы. Также,
так как они подсчитаны, вам не нужно освобождать их из памяти, когда
область действия метода заканчивается, так же как и время жизни объекта - С ИСКЛЮЧЕНИЕМ ПОСЛЕДНЕГО
Поскольку вы используете ОБЪЕКТНУЮ ССЫЛКУ вместо ИНТЕРФЕЙСНОЙ ССЫЛКИ, вы должны освободить
ОБЪЕКТ, который вы создали.
Учитывая код, который вы разместили, если вы присмотритесь, вы фактически найдете ту же ситуацию.
В вашем случае ваш объект полностью реализован в .NET, так что вы пытаетесь
use это Delphi code Wrapper - это ОБЪЕКТ, а не ИНТЕРФЕЙС.
Вы замечаете на обертке, что нет второго способа передать экземпляр
объекта IUserInfo, и это потому, что этот объект не реализует интерфейс,
(ваш объект .NET был создан для этого) - в Delphi вам нужно «выбрать этот интерфейс»
Вы выполнили бы эту задачу, выполнив следующее:
Если вы уже сделали вызов TUserMaintenance.Create (nil) и имеете экземпляр этого объекта,
получить интерфейс по умолчанию, затем «привести» его к соответствующему реализованному интерфейсу
var
UMDelphiWrapper: TUserMaintenance;
UIDelphiWrapper: TUserInfo;
UI: IUserInfo;
UM: IUserMaintenance;
begin
//this part creates a Delphi OBJECT reference to the Implementation class -
//this is NOT Reference counted, because it doesn't implement an interface.
UIDelphiWrapper:=TUserInfo.Create(nil);
try
//this is the part where you acquire the interface of the object that actually
//implementes this interface - e.g. your .NET class
//not that this is the INTERFACE reference - which WILL be reference counted
UI:=UIDelphiWrapper.DefaultInterface as IUserInfo;
//UI.<Set some properties of your IUserInfo object>
try
//this part creates a Delphi OBJECT reference to the Implementation class -
//this is NOT Reference counted, because it doesn't implement an interface.
UMDelhpiWrapper:=TUserMaintenance.Create(nil);
try
//this is the part where you acquire the interface of the object that actually
//implementes this interface - e.g. your .NET class
//not that this is the INTERFACE reference - which WILL be reference counted
UM:=UMdelphiWrapper.DefaultInterface as IUserMaintenance;
try
//Here, you have an interface type implemented by your .NET class that you are
//sending to the implementation of your management object (Also a .NET class)
UM.SendUser(UI);
//do whatever else you need to do with your interface and user/management .NET object(s)
finally
//this IS a reference counted COM object - no "free" necessary
//this would naturally happen when the reference goes out of scope in the method
//but for clairity sake is set to NIL to explicitly release your reference
UM:=nil;
end;
finally
//This is a delphi object that is NOT reference counted and must be released
FreeAndNil(UMDelphiWrapper);
end;
finally
//this IS a reference counted COM object - no "free" necessary
//this would naturally happen when the reference goes out of scope in the method
//but for clairity sake is set to NIL to explicitly release your reference
UI:=nil;
end;
Finally
//This is a delphi object that is NOT reference counted and must be released
FreeAndNIl(UIDelphiWrapper);
end;
В дополнение к фактическому использованию оболочек, предоставляемых Delphi, вы можете вместо этого напрямую создавать ссылки на ваши объекты .NET, если вы знаете правильную информацию.
var
UI: IUserInfo;
UM: IUserManager;
begin
UI:=CreateOleObject('YourAssembly.YourImplementationClass') as IUserInfo;
UI.SomeProperty:=SomeValue;
UM:=CreateOleObject('YourAssembly.YourImplementationClass') as IUserManger;
UM.SomeMetohd(UI);
end;
Этот код намного чище - однако вы все равно должны иметь точное определение IUserInfo и IUserMaintenance, а также знать понятное для класса имя ваших объектов, поскольку они были зарегистрированы в COM.
Вы могли бы сделать это самостоятельно, набрав код - это то, что должна была бы сделать функция импорта типов, когда вы импортировали открытую для COM DLL из вашей сборки. Я не видел фактическую реализацию в коде, который вы предоставили, но вы все равно должны найти эту информацию в вашем заголовочном файле. - Если вы этого не сделаете, значит, вы не импортировали правильную сборку или импорт Delphi 7 работал неправильно - или его необходимо обновить (например, вы добавили новые методы в вашу реализацию .NET, но не сделали этого). • повторно зарегистрируйтесь (с помощью COM) и повторно импортируйте информацию о новом типе сборки).
type
IUserInfo = interface
['22222222-2222-2222-2222-AAAAAAAAAAAA']
//define your methods
end;