InteropServices: How to map .NET data type to LPVOID

  • Thread starter Thread starter LongBow
  • Start date Start date
L

LongBow

Hello,

I am attempting to create an application that uses an existing driver
interface API using C#. I have an API that looks like

F32x_Read( HANDLE Handle, LPVOID Buffer, DWORD NumBytesToRead, DWORD
*NumBytesReturned)

Where the following arguments are described as

Handle - Handle to the device to read as returned by SI_Open
Buffer - Address of a character buffer to be filled with read data
NumBytesToRead - Number of bytes to read from the device into the
buffer(0-64KBytes)
NumBytesReturned - Address of a DWORD which will contain the number of bytes
actually read into the buffer

Within a class I have the DLLImport defined as

[DllImport( "SiF32xUSB.DLL", EntryPoint = "F32x_Read", SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall )]
private static extern unsafe
System.Int32 F32x_Read( System.UInt32 Handle,
System.IntPtr Buffer,
System.UInt32 NumBytesToRead,
System.UInt32* NumBytesReturned
);

But I can't see to figure out how to define the public method that the
application will consume this interface. I know that I need a "fixed"
declaration so the Buffer and NumBytesReturned are pinned, but I don't know
what .NET data type should I use for the IntPtr. I always get compile errors
if I used either string, char, byte.

There is another API that is similar to this one that takes a LPVOID Buffer
that returns a null terminated string, but doesn't tell me how many character
were copied. In addition, the buffer needs to be up to 256. Once I know the
correct data type to use will the ToString() method convert copied data into
the buffer to the correct length or do I need to perform some sort of
manipulation? Any help is greatly appreciated. Thanks

Mark
 
Hello,

You should declare a byte[] array large enough to fit the data read, then
pin the array in memory by using GCHandle.Alloc, and then perform an
explicit type conversion of the obtained GCHandle to IntPtr. This will be
the IntPtr you shoud pass to the unmanaged F32x_Read function. You should
also re-declare the P/Invoke declaration like this:

[DllImport( "SiF32xUSB.DLL", EntryPoint = "F32x_Read", SetLastError = true,
CharSet = CharSet.Unicode, ExactSpelling = true,
CallingConvention = CallingConvention.StdCall )]
private static extern
System.Int32 F32x_Read( System.UInt32 Handle,
System.IntPtr Buffer,
System.UInt32 NumBytesToRead,
ref System.UInt32 NumBytesReturned
);

(no need for unsafe).
 
Back
Top