0

I have to call from a C# application a C function (from a DLL) declared as:

void fillBuffer( uint8_t ** pData, uint32_t * size );

This function checks if pData is not null and in case it fills the buffer with some fancy data. The variable size it is used as input parameter to limit the number of bytes that will be written in pData, and as output parameter to inform how many bytes have been actually written.

In case pData is null, it will allocate the buffer itself and will return in size the number of bytes allocated.

How I can declare and call this function from a C# application (avoiding unsafe if possibile) in both scenarios (passing an already allocated buffer or letting it allocates for me)?

Kill KRT
  • 1,101
  • 2
  • 17
  • 37
  • Declare an overload with `ref IntPtr` that passes `IntPtr.Zero`, and make sure you use the proper function to deallocate the returned memory later. – GSerg Feb 23 '19 at 11:57
  • When you call a method data is stored on the execution stack and is not valid after you return from method. So if your c++ is trying to return data as a pointer the data can be destroyed. So you have to use one of three methods 1) Allocate the maximum size of the return data before calling the c++ method 2) Have c++ allocate the return data using the windows allocation method. Then return pointer to allocated data. You must remember to deallocate this data so you do not get memory leak 3) Call c++ and have the size returned only. Then allocate size and call method again. – jdweng Feb 23 '19 at 13:14
  • @jdweng You seem to be confusing [returning pointers to local variables](https://stackoverflow.com/q/6441218/11683) with returning pointers to memory allocated on the heap. The latter is a common pattern and is perfectly doable with C# + C as long as the C side tells you with what you need to deallocate the memory. An example is [`FormatMessage`](https://learn.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-formatmessage) that tells you to use [`LocalFree`](https://learn.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-localfree). – GSerg Feb 23 '19 at 16:08
  • @GSerg : I know what I'm saying. You are just proposing my method 2 except instead of using the windows allocate method you are saying to use c++ heap. Which is doable except c# cannot deallocate from the heap and would have to call c++ to do the deallocate. While using Windows Allocation the c# can call the c# deallocate directly. – jdweng Feb 23 '19 at 17:20

2 Answers2

0

I think I solved using this solution:

...
UInt32 len;
IntPtr ppData = IntPtr.Zero;

fillBuffer( ref ppData, out len );
...

And declaring the function as following:

 [DllImport( "mylib.dll", CallingConvention = CallingConvention.Cdecl )]
 static extern void fillBuffer( ref IntPtr ppData,out UInt32 size );

Thank you

Kill KRT
  • 1,101
  • 2
  • 17
  • 37
-2

You cant call C functions without unsafe context. This is simply not possible. You cant use unsafe pointers in managed context unless you declared so.

Alan Turing
  • 2,482
  • 17
  • 20