Fog Creek Software
Discussion Board

Welcome! and rules

Joel on Software

pinvoke problem - array of structures

I'm trying to call from .NET a DLL which has a the following function:

struct Foo {
  // only ints, shorts and bytes here

int FooBar(Foo **ppFoos, int *pCount);

which allocates memory, stores there a number of Foo structs,
returns a pointer to them in *ppFoos, and returns their count in *pCount.

As far as I did RTFMSDN, there's no way to do it - they support
marshaling of either variable-size arrays of primitive types in the unmanaged-to-managed direction,
or fixed-size arrays of arbitrary structs, but not buth (variable-size, arbitrary structs).

In desperation I tried to read it into a byte[] array via IntPtr and Marshal.Copy, as in
one of the examples for unmanaged-to-managed marshaling, but something
is wrong again - I get a null reference exception right on the Marshal.Copy call when
I try to read the proper size from the array (count * sizeof); reading just part of the data
works. (And yes, the sizeofs of the structs on both sides are the same.)

Any ideas? What is the *proper* way of doing this, or am I stuck in writing
a wrapper DLL in C++ which does the marshaling for me?

Wednesday, December 3, 2003

Check out Marshal.PtrToStructure.  You need to use this for each element in the unmanaged array to convert them to managed structures.

Wednesday, December 3, 2003

But how do I advance the pointer masquerading as IntPtr between successive structures in the array?

(BTW, I gave up on that, and wrote a thin C++ DLL wrapper that replaced the get-array-of-structures interface with a get-one-structure-by-index interface.)

Thursday, December 4, 2003

Use Marshal.SizeOf.  Something like:
    ptr = (IntPtr)((int)ptr + Marshal.SizeOf(typeof(Foo)));

If you're using C#, you could also accomplish this with 'unsafe' and pointer arithmetic. 

Thursday, December 4, 2003

*  Recent Topics

*  Fog Creek Home