views:

246

answers:

1

I have a 3rd party COM libary that I'm consuming and am having problems with array parameters.

The method signature that I'm calling is as follows:

int GetItems(ref System.Array theArray)

The documentation says that the method's return value is the number of items it will populate into the array, but when it get's called, all of the values in the array are just default values (they are structs) even though the method returns a non-zero return value.

I know there's some funky COM interop stuff going on here, but I really don't have much experience with it and can't figure it out. This is how I've tried to access it:

Array items = Array.CreateInstance(typeof(structItem), 100);
int numberOfItems = instance.GetItems(items);

Array items = Array.CreateInstance(typeof(structItem), 100);
int numberOfItems = instance.GetItems(ref items);

structItem[] items = new structItem[100];
int numberOfItems = instance.GetItems(items);

structItem[] items = new structItem[100];
int numberOfItems = instance.GetItems(ref items);

What am I doing wrong?

UPDATE: I think it might have something to do with SafeArrays, as described here: http://www.west-wind.com/Weblog/posts/464427.aspx The difference is that I'm supposed to pass in the array by ref, not just handle a return value. The specific solution from this article does not work, but I feel like I'm getting warmer.

A: 

It's been a while since I did any Interop so I'm not sure, but I think you should be allocating unmanaged memory to send to the COM library. I'd look at the Marshal class, especially Marshal.AllocHGlobal (you probably have to use FreeHGlobal to free the memory aftwards though).

Something like this maybe:
IntPtr p = Marshal.AlloHGlobal(items.Length * Marshal.SizeOf(typeof(structItem));
Marshal.Copy(items, 0, p, items.Length);

ho1