Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I pass an instance of a .NET COM object from Delphi to another .NET COM object?
    primarykey
    data
    text
    <p>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.</p> <p>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 <em>another</em> object (that has been defined-registered-exported-blah-blah-blah as above) as a parameter to a method on the first module.</p> <p><strong>.NET</strong></p> <pre><code>[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; } } </code></pre> <p>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 <em>not</em> use the I-interfaces that I declared in .NET at all.</p> <p><strong>Delphi</strong></p> <pre><code>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; </code></pre> <p>Delphi has also created the corresponding Delphi types:</p> <pre><code>// *********************************************************************// // 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; </code></pre> <p>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.</p> <p>Admittedly, this is a much simplified example of my actual issue, but I think that it sufficiently illustrates the problem.</p> <p>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 <em>another</em> way that I can pass an instance of UserInfo to UserMaintenance?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload