Implementing an Existing COM Interface in Managed Code which RETURNS an Array of COM Structures RRS feed

  • Question

  • I'm trying to evolve from COM to .NET by slowly replacing COM implementations of COM Interfaces with .NET implementations of the same interfaces and I'm struck.  I have no problem with arrays of COM structures built in COM programs and passed to .NET.  But when a COM program uses a COM Inteface implemented with C# .NE and expects an array of a given structure to be returned, it just doesn't work...  There are hundreds of methods and many dozens of structures

    Here is a simple COM Structure definition IDL:

     typedef [uuid(EE3337E6-14F7-469b-BE9F-8D45FA43F4ED)]
     struct EATemplate_ACT
      long TemplateID;
      BSTR TemplateName;
     } EATemplate_ACT;

    Here is an COM interface definition:

    library EADimensionLib

     //  Forward Declarations
        //  ====================
      interface IEADimensionAC;
    //  IEADimensionAC - 
    //  ==========================================

         interface IEADimensionAC : IDispatch

      //  Get Templates Method
      //  ======================
       [id(1), helpstring("Gets Templates")]
       HRESULT GetTemplates
        // Parameters
        [in, out] SAFEARRAY(struct EATemplate_ACT)* Templates,

        // Return
        [out, retval] long* Size

    I want to implement GetTemplate's in C# as a COM interface so that existing programs can begin to use the new C#, WCF based logic.  I have no problem calling the current COM implementation from .NET code, but replacing the COM implementation with .NEt code just isn't working.
    The following code, compiles with a warning but the resulting interface is not operational in COM programs.
    namespace EAClientWS
    public class CDimensionLocators : EADimensionLib.IEADimensionAC
     EADomainWSClient m_oDomainProxy = new EADomainWSClient();
     public int GetTemplates(ref Array Templates)
      int lCount = 0;
      int i = 0;
      Dimension[] dimTemplates = null;
      EAACTLib.EATemplate_ACT[] MyTemplates = null;
      lCount = m_oDomainProxy.GetTemplates(ref dimTemplates);
      if (lCount == 0)
       return 0;
      MyTemplates = new EAACTLib.EATemplate_ACT[lCount];
      foreach (Dimension vTemplate in dimTemplates)
       MyTemplates[i].TemplateID = vTemplate.DimensionID;
       MyTemplates[i].TemplateName = vTemplate.DimensionName;

      Templates = MyTemplates;
      return lCount;

    The interop books just show one way from COM -> .NET, but that leaves me with a big conversion.
    Peter Boswell
    MSDOS 1.0 Developer

    Thursday, October 23, 2008 7:21 PM


  • Declaring it as EATemplate_ACT[] ought to work.  Without the "ref" keyword.
    Hans Passant.
    • Marked as answer by Zhi-Xin Ye Thursday, October 30, 2008 2:36 AM
    Friday, October 24, 2008 12:00 AM