Click here to Skip to main content
15,888,527 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
This is a bit of an interop question, so I thought I'd ask those wiser than me (so, that's most of you...)

I have a bit of C# code, wrapped up in COM:

C#
namespace Blah
{
  public interface Blether
  {
...
    [DispId(19)]
    int IainTest(ref byte[] Hello);
  }
}


I am setting up a variant as a parameter to IDispatch::Invoke. If "Hello" were string then I'd have:

C++
vtParam [n].vt = VT_BSTR;
vtParam [n].bstr = ...;


If it was ref string, I'd have:

C++
vtParam [n].vt = VT_BSTR | VT_BYREF;
vtParam [n].bstr = ...;


If it was an array of bytes, I have:
C++
vtParam [n].vt = VT_UI1 | VT_ARRAY;
vtParam [n].parray = pMySafeArrayOfBytes;


All of the above works.

But I'm failing on the top example: An in/out array parameter. I've tried:
++
vtParam [n].vt = VT_UI1 | VT_ARRAY | VT_BYREF;
vtParam [n].parray = pMySafeArrayOfBytes;


But I get a crash in the COM marshalling code. Looking at the assembly, it appears to be checking for VT_ARRAY, masking out VT_ARRAY, then looking at what's left - and that's not a simple type.

Any tips?

Iain.
Posted

if that works
C#
vtParam [n].vt = VT_UI1 | VT_ARRAY;
vtParam [n].parray = pMySafeArrayOfBytes;


dont use the VT_BYREF flag. This will transport a pointer, which is invalid/inaccessable in another process.

Consider marshalling as a "package service" which want to deliver packets od data not references...
 
Share this answer
 
Comments
Iain Clarke, Warrior Programmer 31-May-13 7:45am    
Well, I can do VT_BYREF | VT_I4 to "connect" to a (..., ref int, ...) function, so the marshaller is clever enough there. Just VT_ARRAY | x means the marshaller has to package up a safearray with its contents to pass to the other end too.

My problem is that the marshaller does not "bring back" the array afterwards...

I have done some reading into MarshalAs which started to look hopeful, but that might be just for C# to c++ (ie, PInvoke), not COM to C#.

Iain.
In VARIANT structure, you will see member named pparray without any document in MSDN. I try to use it to pass an SafeArray to SAFEARRAY** (in idl) parameter, like this:
C++
vtParam[n].vt = VT_I4 | VT_ARRAY | VT_BYREF;
vtParam[n].pparray = &mySafeArrayPointer; // use address of your safeArrayPointer


Remember to free it~
 
Share this answer
 
v3

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900