I have a legacy app written in Delphi 7. We are adding new modules to the app. The modules are written in Visual Studio 2010, .NET 4, C#, and exposed to the app through COM.
I have successfully defined a class, registered the assembly, exported the type library, imported the type library into Delphi, created the COM client in Delphi and executed the module. Now comes the tricky part: I want to pass another object (that has been defined-registered-exported-blah-blah-blah as above) as a parameter to a method on the first module.
.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;
}
}
Assuming that I have separate classes implementing each interface, and the assemblies containing those classes compile and register successfully, I import the type libraries into Delphi creating UserMaintenance_TLB.pas and UserInfo_TLB.pas. However, I see something unexptected: while the interfaces that I defined in .NET exist (the ones beginning with "I"), Delphi has generated another set of interfaces (the ones beginning with "_"). Delphi does not use the I-interfaces that I declared in .NET at all.
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 has also created the corresponding Delphi types:
// *********************************************************************//
// 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;
What I would like to do is create an instance of TUserMaintenance, and then pass an instance of TUserInfo to it. However, two things are immediately obvious: The Delphi class TUserInfo does NOT implement IUserInfo, and the DefaultInterface is the new interface that Delphi generated, _UserInfo. I cannot declare my UserInfo variable as type IUserInfo because TUserInfo does not implement the interface. Nor can I declare it as type _UserInfo because UserMaintenance.LoadUser expects an IUserInfo instance.
Admittedly, this is a much simplified example of my actual issue, but I think that it sufficiently illustrates the problem.
So my question is this: is there any way for me to force the interface type in Delphi to remain consistent with the interface that is declared in .NET? Or is there another way that I can pass an instance of UserInfo to UserMaintenance?