By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,946 Members | 773 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,946 IT Pros & Developers. It's quick & easy.

how to pass array from managed to COM

P: n/a
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
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

Mar 16 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
"Boni" <no****@parampam.pam> wrote in message
news:OB**************@TK2MSFTNGP10.phx.gbl...
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
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

Your function definion is: STDMETHOD(myfunc)(INT* array)

From this function definition it is not clear what the size of the array
should be. I assume that the client and the server know the size of the
array for a reason not described so far. In this case you should define you
P/Invoke function like this:

[DllImport("....")]
static extern myfunc([MarshalAs(LPAray int[] rgi);

Marcus
Mar 16 '06 #2

P: n/a
Hi Marcus,
I assume that the client and the server know the size of the array for a
reason not described so far.

No the size is passed as a second function argument (sorry I skiped this in
the description)
STDMETHOD(myfunc)(INT* array, int size).
And I don't use PInvoke explicitely (Visual Studo generats Interop for me).


Mar 16 '06 #3

P: n/a
"Boni" <oilia@nospam> wrote in message
news:uO**************@TK2MSFTNGP11.phx.gbl...
Hi Marcus,
I assume that the client and the server know the size of the array for a
reason not described so far.

No the size is passed as a second function argument (sorry I skiped this
in the description)
STDMETHOD(myfunc)(INT* array, int size).
And I don't use PInvoke explicitely (Visual Studo generats Interop for
me).


The COM Interop Type information generated by VS, by TLBIMP, and by
System::Runtime::Interop::TypeLibConverter is not sufficient for what you
need. This is especially the case, because the COM Type Info does not have
all the information that is necessary.

It is very likely that you have to write the type information yourself.
[
object,
uuid(... your IID ...),
oleautomation
]
interface IYourInterface : IUnknown {
STDMETHOD(myfunc)([size_is(size)] INT* array, int size);
}

in this case, you can define Interop Type Info like this one:

[
Guid("... your IID ..."),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown )
]
public interface IYouInterface
{
void myFunc([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] int[]
rgints, int size);
}


Mar 16 '06 #4

P: n/a
Thanks a lot Marcus, I will try that.
"Marcus Heege" <NO****@heege.net> schrieb im Newsbeitrag
news:%2****************@TK2MSFTNGP14.phx.gbl...
"Boni" <oilia@nospam> wrote in message
news:uO**************@TK2MSFTNGP11.phx.gbl...
Hi Marcus,
I assume that the client and the server know the size of the array for a
reason not described so far.

No the size is passed as a second function argument (sorry I skiped this
in the description)
STDMETHOD(myfunc)(INT* array, int size).
And I don't use PInvoke explicitely (Visual Studo generats Interop for
me).


The COM Interop Type information generated by VS, by TLBIMP, and by
System::Runtime::Interop::TypeLibConverter is not sufficient for what you
need. This is especially the case, because the COM Type Info does not have
all the information that is necessary.

It is very likely that you have to write the type information yourself.
[
object,
uuid(... your IID ...),
oleautomation
]
interface IYourInterface : IUnknown {
STDMETHOD(myfunc)([size_is(size)] INT* array, int size);
}

in this case, you can define Interop Type Info like this one:

[
Guid("... your IID ..."),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown )
]
public interface IYouInterface
{
void myFunc([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] int[]
rgints, int size);
}

Mar 17 '06 #5

P: n/a
Just one more small question
void myFunc([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] int[]

Is the pointer passed to the array a pointer to initial array or to a copy
of this array? I.e. If I change data inside of COM using this pointer, will
initial data change?
Mar 17 '06 #6

P: n/a
No, you pass a copy, so you can't change the managed arry this way.
Anyway, the easiest way of passing array's to/from COM is by means of self
describing SAFEARRAY's. The default COM interop marshaler will take care of
data marshaling for automation types.

IDL:
HRESULT PassInOutIntArray([in, out] SAFEARRAY(long)* arr);

Declaration:
....

STDMETHOD(PassInOutIntArray)(SAFEARRAY ** arr);

Definition:

STDMETHODIMP CTest::PassInOutIntArray(SAFEARRAY ** arr)
{
int* temp;
SafeArrayAccessData(*arr, (void**)&temp);
long ubound;
SafeArrayGetUBound(*arr, 1, &ubound);
for(int i = 0; i <= ubound; i++)
{
temp[i] = temp[i] * 2; // each element * 2
}
SafeArrayUnaccessData(*arr);
S_OK;
}

C#
....
Array iar = new int[10] { 12, 23, 45, 7, 89, 25, 12, 8, 9, 5 };a;
ComObj.PassInOutIntArray(ref iar );
foreach(int in iar)
....

No need to define the interface in C#, just set a reference to the typelib
and you are done.
Willy.
"Boni" <oilia@nospam> wrote in message
news:eq**************@TK2MSFTNGP09.phx.gbl...
| Just one more small question
| >> void myFunc([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)]
int[]
| Is the pointer passed to the array a pointer to initial array or to a copy
| of this array? I.e. If I change data inside of COM using this pointer,
will
| initial data change?
|
|
Mar 17 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.