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?