Click here to Skip to main content
15,901,426 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

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
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.

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