0

I'm trying to call a COM interface function from C# code. This is an aggregated COM interface where I load the implementing COM interface by ProgID and I have to declare the interface myself. The c++ function definition looks like:

STDMETHOD(VisualizeList) (HWND hWndParent, DWORD Options, SAFEARRAY **VialPositions, 
    SAFEARRAY **VialTypes, BSTR* TrayName) = 0;    

The SAFEARRAYs contain strings and integers respectively and are used for both input and output. I've tried defining the function in C# like this:

[PreserveSig]
int VisualizeList([In] IntPtr hwdParent,
    [In] uint Options, 
    [In, Out][MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_BSTR)] ref String[] VialPositions,
    [In, Out][MarshalAs(UnmanagedType.SafeArray, SafeArraySubType=VarEnum.VT_I4)] ref int[] VialTypes,
    [In, Out] ref String TrayName);

But when I attempt to call the interface function, it crashes. I'm thinking its the SAFEARRAYs because everything else seems relatively straight forward. I think I need one more order of referencing for the SAFEARRAYs, but I'm not sure how to do that. So, how do you pass a parameter of type SAFEARRAY** from managed code? I've scanned online and through other posts, but couldn't find anything that quite fit the bill. Thanks in advance.

forother
  • 39
  • 4
  • it could also depends on what you do on the C++ side. – Simon Mourier Feb 24 '17 at 17:52
  • Well, the C++ definition comes from a specification document. I'm not creating the COM implementation, but I do have one that works and I can call it easily enough from c++ native code. I could always make a wrapper for it using C++\CLI, but I was hoping to avoid having to do that. – forother Feb 24 '17 at 18:31
  • What does the IDL declare? What does the type library declare? I'd try declaring those parameters as [out] instead of [ref]. To start with, you could also see what making them generic Object's as [out] parameters would do. – Joseph Willcoxson Feb 24 '17 at 18:48
  • Unfortunately there is no IDL for the interface. The COM servers are mostly implemented in MFC. They usually define the interface in a c++ header and add it to their interface map. So the COM interface isn't registered, you QueryInterface to get it from the servers. Anyway, the root of the problem I think is the the SAFEARRAY**. I think if it were just SAFEARRAY* it wouldn't be a problem. – forother Feb 24 '17 at 21:19
  • There may not be an IDL file, but you can reverse engineer one for the type library. It has to have a type library. Find out where the type library is (probably in the DLL) and use OleView which comes with Visual Studio to look at how the arguments are defined. – Joseph Willcoxson Feb 27 '17 at 15:27

0 Answers0