Domanda

I have a native library which passes hardware data to managed code via callbacks.
The basic native-to-managed plumbing is done by

[DllImport("Library.dll")]
public static extern bool Init(IntPtr dataCallBack)

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void Data(string data);

...

var handler = Marshal.GetFunctionPointerForDelegate(HandleData);
Init(handler);

...

private static void HandleData(string data)
{
    //use data
}

The above works just fine.
However, because HandleData can be called hundreds or even thousands of times a second (depending on the exact hardware module) and the data string can also be quite long, it creates a noticeable pressure on the GC.

I would like to avoid the creation of all those strings and instead receive the data as char[] or even byte[] as I just need to extract a few fields.
I tried to substitute 'string' with StringBuilder or char[] but that didn't work.

Additional information:
- The native library passes the data as char * (null terminated string)
- The memory is allocated and released by the native code
- .NET version: 4.5

I would appreciate your help.
Thank you!

È stato utile?

Soluzione

Have you tried changing callback signature like this?

[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void Data(IntPtr data);


private unsafe static void HandleData(IntPtr data)
    {
        byte* charPtr = (byte*)data;

        // work with bytes here (which are single-byte chars).


    }

Here you need to be cautios and check for null character manually.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top