У меня есть устаревшее приложение, написанное на Delphi 7. Мы добавляем в приложение новые модули. Модули написаны на Visual Studio 2010, .NET 4, C # и доступны приложению через COM.
Я успешно определил класс, зарегистрировал сборку, экспортировал библиотеку типов, импортировал библиотеку типов в Delphi, создал COM-клиент в Delphi и выполнил модуль. Теперь наступает сложная часть: я хочу передать другой объект (который был определен-зарегистрирован-экспортирован-бла-бла-бла, как указано выше) в качестве параметра метода в первом модуле.
.NET
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("11111111-1111-1111-1111-AAAAAAAAAAAA")]
public interface IUserMaintenance
{
bool AssignUser(IUserInfo);
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("11111111-1111-1111-1111-BBBBBBBBBBBB")]
public class UserMaintenance: IUserMaintenance
{
private IUserInfo _UserInfo;
public bool AssignUser(IUserInfo userInfo)
{
_UserInfo = userInfo;
LoadUser();
}
private void LoadUser()
{
//load user data from database using _UserInfo.UserName
}
}
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("22222222-2222-2222-2222-AAAAAAAAAAAA")]
public interface IUserInfo
{
void Initialize(string userName);
string UserName { get; }
}
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("22222222-2222-2222-2222-BBBBBBBBBBBB")]
public class UserInfo: IUserInfo
{
public string UserName { get; private set };
public void Initialize(string userName)
{
UserName = userName;
}
}
Предполагая, что у меня есть отдельные классы, реализующие каждый интерфейс, и сборки, содержащие эти классы, успешно компилируются и регистрируются, я импортирую библиотеки типов в Delphi, создавая UserMain maintenance_TLB.pas и UserInfo_TLB.pas. Однако я вижу нечто неожиданное: хотя интерфейсы, которые я определил в .NET, существуют (те, которые начинаются с «I»), Delphi сгенерировал другой набор интерфейсов (те, которые начинаются с «_»). Delphi вообще не использует I-интерфейсы, которые я объявил в .NET.
Delphi
UserMaintenance_TLB.pas
// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
IUserMaintenance = interface;
IUserMaintenanceDisp = dispinterface;
_UserMaintenance = interface;
_UserMaintenanceDisp = dispinterface;
UserInfo_TLB.pas
// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
IUserInfo = interface;
IUserInfoDisp = dispinterface;
_UserInfo = interface;
_UserInfoDisp = dispinterface;
Delphi также создал соответствующие типы Delphi:
// *********************************************************************//
// OLE Server Proxy class declaration
// Server Object : TUserMaintenance
// Help String :
// Default Interface: _UserMaintenance
// Def. Intf. DISP? : No
// Event Interface:
// TypeFlags : (2) CanCreate
// *********************************************************************//
TUserMaintenance = class(TOleServer)
private
FIntf: _UserMaintenance;
function GetDefaultInterface: _UserMaintenance;
protected
procedure InitServerData; override;
function Get_ToString: WideString;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Connect; override;
procedure ConnectTo(svrIntf: _UserMaintenance);
procedure Disconnect; override;
function Equals(obj: OleVariant): WordBool;
function GetHashCode: Integer;
function GetType: _Type;
WordBool AssignUser(IUserInfo userInfo);
property DefaultInterface: _UserMaintenance read GetDefaultInterface;
property ToString: WideString read Get_ToString;
published
end;
Что я хотел бы сделать, так это создать экземпляр TUserMainasted, а затем передать ему экземпляр TUserInfo. Однако сразу же очевидны две вещи: класс Delphi TUserInfo НЕ реализует IUserInfo, а DefaultInterface - это новый интерфейс _UserInfo, созданный Delphi. Я не могу объявить свою переменную UserInfo как тип IUserInfo, потому что TUserInfo не реализует интерфейс. Я также не могу объявить его как тип _UserInfo, потому что UserMainauce.LoadUser ожидает экземпляр IUserInfo.
По общему признанию, это намного упрощенный пример моей реальной проблемы, но я думаю, что он достаточно иллюстрирует проблему.
Итак, мой вопрос таков: есть ли у меня способ заставить тип интерфейса в Delphi оставаться согласованным с интерфейсом, объявленным в .NET? Или есть другой способ передать экземпляр UserInfo в UserMainistance?