PInvoke and arrays

  • Thread starter Thread starter Andrea Palmieri
  • Start date Start date
A

Andrea Palmieri

hello everybody,
I exported a function from a dll written in c.
This function has an array of long among the parameters and the content of
the array is modified in the dll function

How can I invoke this function from a c# program ?
I tried
I declared the function as:

public static extern int MyFunction(

[MarshalAs(UnmanagedType.LPArray)] long[] pSlotList);

and invoked it

long[4] v = {0,0,0,0};

n = MyClass.MyFunction(v );



..... but it doesn't work: the content of the array hasn't been modified at
all !!!

any suggestion ?

Thank you

Andrea
 
Andrea,

The P/Invoke layer only marshals back the first value in an array
because it doesn't know how many elements the array can have in memory (when
dealing with C-style arrays). In this case, you will have to marshal the
values back yourself. Either that, or use unsafe code. With unsafe code,
you can do the following:

public unsafe static extern int MyFunction(int *pSlotList);

I use int because it is a 32 bit integer, just as long is in C. A long
in .NET is 64 bits.

Then, you can do the following:

public static int MyManagedFunction(int[] slotlist)
{
// Declare an unsafe block.
unsafe
{
// Fix the array pointer.
fixed (int *pSlotList = slotlist)
{
// Make the call.
return MyFunction(pSlotList);
}
}
}

If you don't like the idea of using unsafe code, then you can use
managed code. The code is much larger, as you would have to use the methods
on the Marshal class to create an unmanaged memory block and then write the
values in the array one at a time to the unmanaged memory. Then you would
pass this to the DLL function, and on return, read the values from memory
(using the Marshal class once again), and deleting the unmanaged memory.

Hope this helps.
 
Nicholas Paldino said:
The P/Invoke layer only marshals back the first value in an array
because it doesn't know how many elements the array can have in memory (when
dealing with C-style arrays).

I don't think this is correct. I constantly pass byte arrays to the Windows
API and when the function returns the byte array is successfully updated [as
expected]. My advice to the OP is to get rid of the MarshalAs attribute.
I've never used it for arrays and it always worked perfectly. Also, a C
declaration of the function you're calling would be helpful.

Regards,
Pieter Philippaerts
Managed SSL/TLS: http://www.mentalis.org/go.php?sl
 
Back
Top