views:

30

answers:

0

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?

related questions