none
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
    {
     importlib("stdole32.tlb");
     importlib("stdole2.tlb");
     importlib("..\eaact\eaact.tlb");

     //  Forward Declarations
        //  ====================
      interface IEADimensionAC;
     
    //  IEADimensionAC - 
    //  ==========================================
     [
      odl,
      uuid(9FDE51BA-C965-4beb-AEA4-27C9F25C99C0),
      version(1.0),
            nonextensible,
            oleautomation,
         dual,
      pointer_default(unique)
     ]

         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
    {
    [GuidAttribute("0223F301-E827-4fb7-B55B-AC3C658CEAEA")]
    [ProgIdAttribute("EAClientWS.CDimensionLocators")]
    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;
       i++;

      }
      Templates = MyTemplates;
      return lCount;
     }
    }

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

    Thursday, October 23, 2008 7:21 PM

Answers

  • 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
    Moderator