Passing memory pointer to unmanaged C++ dll

G

Guest

I have a dll that takes a byte pointer. Similar to this:

writeDataToBuffer(byte *buffer, int *BufferSize);

The buffer is allocated by the dll.

I have no problem with the BufferSize parameter it is the buffer parameter
that I am not sure of the best way to handle. What is the recommended way to
call this function from C#?

I appreciate any help or documentation pointers that anyone can supply.

thanks,
-joe-
 
M

Michael C

Joe Tavares said:
I have a dll that takes a byte pointer. Similar to this:

writeDataToBuffer(byte *buffer, int *BufferSize);

You can just do it like this:

[DllImport("kernel32", EntryPoint= "GetComputerNameA")]
private static extern int GetComputerName(byte[] lpBuffer, ref int nSize);

or like this:

[DllImport("kernel32", EntryPoint= "GetComputerNameA")]
private static extern int GetComputerName(IntPtr lpBuffer, ref int nSize);

[STAThread]
static void Main()
{
byte[] data = new byte[256];
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
int size = data.Length;
GetComputerName(handle.AddrOfPinnedObject(), ref size);
handle.Free();

Michael
 
M

Michael C

Joe Tavares said:
I have a dll that takes a byte pointer. Similar to this:

writeDataToBuffer(byte *buffer, int *BufferSize);

Oops, I just read this bit:
The buffer is allocated by the dll.

In that case you should do it like this:

[DllImport("kernel32", EntryPoint= "GetComputerNameA")]
private static extern int GetComputerName([Out] out IntPtr lpBuffer, ref int
nSize);

and then use Marshal.Copy to copy the data to a local buffer.

I don't have something to test but I'm pretty sure you'll need to [Out] out
so the dll can return a pointer.

On second thoughts are you sure your C dll allocates the buffer, shouldn't
it be "byte **buffer" then?

Michael
 
G

Guest

Michael,
You are correct that it is Byte **, it was a typo on my part. Thank you very
much for the help. Your advice was right on and helped me to move forward
with the project. I actually took your first example in the previous post
(Byte[]buffer) and wrote a C++ wrapper around the memory
allocation/deallocation and have everything working perfectly now.

-joe-

Michael C said:
Joe Tavares said:
I have a dll that takes a byte pointer. Similar to this:

writeDataToBuffer(byte *buffer, int *BufferSize);

Oops, I just read this bit:
The buffer is allocated by the dll.

In that case you should do it like this:

[DllImport("kernel32", EntryPoint= "GetComputerNameA")]
private static extern int GetComputerName([Out] out IntPtr lpBuffer, ref int
nSize);

and then use Marshal.Copy to copy the data to a local buffer.

I don't have something to test but I'm pretty sure you'll need to [Out] out
so the dll can return a pointer.

On second thoughts are you sure your C dll allocates the buffer, shouldn't
it be "byte **buffer" then?

Michael
 
M

Michael C

Joe Tavares said:
Michael,
You are correct that it is Byte **, it was a typo on my part. Thank you
very
much for the help. Your advice was right on and helped me to move forward
with the project. I actually took your first example in the previous post
(Byte[]buffer) and wrote a C++ wrapper around the memory
allocation/deallocation and have everything working perfectly now.

You can get away without the wrapper but if you do write one another option
is to write it as a dot net dll in C++. This is easy to do (even I managed
to do it) as the wizards step you through everything. Then you can add the
dll as a managed reference.

Michael
 

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