pass array from managed code to COM object

B

Boni

Dear all,
I have written a C++ com object:
STDMETHOD(myfunc)(INT* array)



Now I need to pass an array from c# to com. I generated a COM interop and it
the signature of the function is

myfunc(ref int)

in C# I have an array of ints.

If I call

myfunc(array[0])

and try to access from COM object the array[1],2.... they are incorrect.
Only array[0] is correct. What do I do wrong?

Thanks a lot,

Boni
 
W

Willy Denoyette [MVP]

| Dear all,
| I have written a C++ com object:
| STDMETHOD(myfunc)(INT* array)
|

Well, you declared the function to pass a pointer to an int.

|
|
| Now I need to pass an array from c# to com. I generated a COM interop and
it
| the signature of the function is
|
| myfunc(ref int)
|

See, ref int, is a pointer to an int.

| in C# I have an array of ints.
|
| If I call
|
| myfunc(array[0])
|

Here you pass the adress of the first element in the array of int's.

| and try to access from COM object the array[1],2.... they are incorrect.
| Only array[0] is correct. What do I do wrong?
|

The first element is correct, that's exactly what you have asked for, right?

You need to declare the argument as an array of int's in your C++ code and
pass the array reference from C#.

Willy.
 
B

Boni

You need to declare the argument as an array of int's in your C++ code and
pass the array reference from C#.
Can you give a pseudocode on C++ and C#side? I am not sure, how should I do
that.
I don't know size of an array on C++ side, it is passed thru other function,
and I think INT[] array will make no difference with pointer.
 
W

Willy Denoyette [MVP]

|> You need to declare the argument as an array of int's in your C++ code
and
| > pass the array reference from C#.
| Can you give a pseudocode on C++ and C#side? I am not sure, how should I
do
| that.
| I don't know size of an array on C++ side, it is passed thru other
function,
| and I think INT[] array will make no difference with pointer.
|
|

Well, there different ways to pass an array to/from COM.
If you want to pass a self describing array you need to use the SAFEARRAY
type, this is also the default used by the COM marshaler.

Say you have the following in IDL:
.... HRESULT PassStringArray([in] SAFEARRAY(BSTR) arr);

Your implementation should look something like this:

STDMETHODIMP CTest::passStringArray(SAFEARRAY * arr)
{
BSTR* temp;
SafeArrayAccessData(arr, (void**)&temp);
long ubound;
SafeArrayGetUBound(arr, 1, &ubound);
for(int i = 0; i <= ubound; i++)
printf_s("%S\n", temp);
SafeArrayUnaccessData(arr);
return S_OK;
}

And you call it from C# like:
....
string[] arr = new string[] { "Hello", "World" };
obj.PassStringArray(arr);

Another option is to pass native C style arrays,
Please consult "Default Marshaling for Arrays" in MSDN for more info.

Willy.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top