I've got a C# program that needs to pass a char buffer to an unmanaged function. I've found two ways that seem to work reliably, but I'm not sure which I should choose.
Here's the unmanaged function's signature.
extern "C" __declspec(dllexport) int getNextResponse(char *buffer);
The first option is to define the buffer as a StringBuilder, as follows.
//at class level...
[DllImport("mydll.dll")]
static extern int getNextResponse(StringBuilder buffer);
//in main method body...
StringBuilder sb = new StringBuilder(" ", 65536);
int rc = getNextResponse(sb);
This is simple, and it works, and I think I basically understand why it works because the StringBuilder has a buffer behind the scenes, so (I assume) the interop layer is just marshalling the StringBuilder to a char *.
The other option is using unsafe code.
//at class level...
[DllImport("mydll.dll")]
static extern int getNextResponse(byte* buffer);
//separate method...
private static unsafe int runGetNextResponse(byte[] buffer)
{
fixed (byte* p = buffer)
{
int rc = getNextResponse(p);
return rc;
}
}
//in main method body...
byte[] b = new byte[65536];
int rc = runGetNextResponse(b);
The second approach is more code, but it's also more explicit about what's going on.
Are these two approaches doing basically the same thing? Is there any reason to choose one over the other?