A hint on marshalling a byte array into a void* pointer

B

Beorne

I have to pass a byte array as an input parameter to a function in a
propertary dll.
The c++ signature of the original function is the following:

---------- C++ ----------

int ncWrite(unsigned long ObjHandle, unsigned long DataSize, void*
DataPtr)

---------- end C++ ----------
From C# I have defined this function as:

---------- C# ----------

[DllImport("Nican.dll")]
unsafe static extern int ncWrite(uint ObjHandle, uint DataSize,
IntPtr DataPtr);

---------- end C# ----------

And I use it as:

---------- C# ----------

byte[] DataWrite = {0x23, 0x23, 0x30, 0x03, 0x78, 0xEC, 0xFF, 0xFF };
int myStatus;

IntPtr ptr = Marshal.AllocHGlobal(8);
Marshal.Copy(DataWrite, 0, ptr, 8);
myStatus = ncWrite(WriteAddress, 8 , ptr);
Marshal.FreeHGlobal(ptr);

---------- end C# ----------

This works, but having to handle unmanaged code I''m worried by memory
leaks (this function is called thousdands of times per minute).
Is it the usage correct? Have I choosen the right Marshal methods
(Marshal.AllocHGlobal, Marshal.Copy, Marshal.FreeHGlobal)?

Thank you very much
 
C

Christof Nordiek

Beorne said:
From C# I have defined this function as:

---------- C# ----------

[DllImport("Nican.dll")]
unsafe static extern int ncWrite(uint ObjHandle, uint DataSize,
IntPtr DataPtr);

---------- end C# ----------

And I use it as:

---------- C# ----------

byte[] DataWrite = {0x23, 0x23, 0x30, 0x03, 0x78, 0xEC, 0xFF, 0xFF };
int myStatus;

IntPtr ptr = Marshal.AllocHGlobal(8);
Marshal.Copy(DataWrite, 0, ptr, 8);
myStatus = ncWrite(WriteAddress, 8 , ptr);
Marshal.FreeHGlobal(ptr);

---------- end C# ----------

This seems to be OK. You should add a try/finally to get sure the memory
gets cleared in case of an exception.

IntPtr ptr = Marshal.AllocHGlobal(8);
try
{
Marshal.Copy(DataWrite, 0, ptr, 8);
myStatus = ncWrite(WriteAddress, 8, ptr);
}
finally
{
Marshal.FreeHGlobal(ptr);
}

Christof
 
S

Stephen Martin

You don't really need to manually marshal the data. Change your C#
declaration to:

[DllImport("Nican.dll")]
unsafe static extern int ncWrite(uint ObjHandle, uint DataSize, byte[]
DataPtr);

and then just pass in DataWrite as is. The runtime marshaller will pin your
array and then pass in a pointer to the unmanaged function.



Beorne said:
I have to pass a byte array as an input parameter to a function in a
propertary dll.
The c++ signature of the original function is the following:

---------- C++ ----------

int ncWrite(unsigned long ObjHandle, unsigned long DataSize, void*
DataPtr)

---------- end C++ ----------
From C# I have defined this function as:

---------- C# ----------

[DllImport("Nican.dll")]
unsafe static extern int ncWrite(uint ObjHandle, uint DataSize,
IntPtr DataPtr);

---------- end C# ----------

And I use it as:

---------- C# ----------

byte[] DataWrite = {0x23, 0x23, 0x30, 0x03, 0x78, 0xEC, 0xFF, 0xFF };
int myStatus;

IntPtr ptr = Marshal.AllocHGlobal(8);
Marshal.Copy(DataWrite, 0, ptr, 8);
myStatus = ncWrite(WriteAddress, 8 , ptr);
Marshal.FreeHGlobal(ptr);

---------- end C# ----------

This works, but having to handle unmanaged code I''m worried by memory
leaks (this function is called thousdands of times per minute).
Is it the usage correct? Have I choosen the right Marshal methods
(Marshal.AllocHGlobal, Marshal.Copy, Marshal.FreeHGlobal)?

Thank you very much
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top