Further to Todd Gayley's answer on string handling in a DLL function, I have the following code:
Needs["NETLink`"]
InstallNET["Force32Bit" -> True];
maxBufLen = 2048;
LoadNETType["System.Runtime.InteropServices.Marshal"];
buf = Marshal`AllocHGlobal[maxBufLen];
sqlfunction = DefineDLLFunction["getSQL", "Server.dll", "int", {"int", "IntPtr", "int"}];
selKey = 9591556;
sqlfunction[selKey, buf, maxBufLen];
numBytes = 1024;
managedArray = NETNew["System.Byte[]", numBytes];
Marshal`Copy[buf, managedArray, 0, numBytes];
bytes = NETObjectToExpression[managedArray];
sql = StringJoin@FromCharacterCode[DeleteCases[SplitBy[bytes, # != 0 &], {0 ..}]]
This works quite well except, unlike in Todd's example, sqlfunction
does not return the number of bytes it has put into the buffer buf
. In the code above I use 1024 bytes, but this can result in the final string being padded out with random junk from the buffer. Is there a way to fill the buffer with whitespace prior to use by sqlfunction
?
There are some solutions here: How to zero out memory allocated by Marshal.AllocHGlobal? but I'm not sure how to implement them in NETLink.