I'm trying to pass a writable (pre-allocated) string array from C# to a C++ dll. It fails with "Access violation writing location".
C++:
int StringArrayTest(size_t numberOfStrings, char **valueOut, size_t maxStringLength) {
for (unsigned int i = 0; i < numberOfStrings; i++) {
auto str = std::to_string(i); //Create simple string
strncpy(valueOut[i], str.c_str(), maxStringLength); //Copy to output
}
return 0;
}
C#:
[DllImport("MyDLL", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
static extern int StringArrayTest(ulong arraySize, [MarshalAs(UnmanagedType.LPArray)]StringBuilder[] valuesOut, ulong maxStringLength);
public string[] GetTestStrings(ulong arraySize, ulong maxStringLength) {
var stringBuilder = new StringBuilder[(int)arraySize];
for (var i = 0; i < (int)arraySize; i++) {
stringBuilder[i] = new StringBuilder((int)maxStringLength);
}
var result = StringArrayTest(arraySize, stringBuilder, maxStringLength);
var returnValues = new string[arraySize];
for (var i = 0; i < (int)arraySize; i++) {
returnValues[i] = result.ToString();
}
return returnValues;
}
Note that doing this with a single string (char * signature and passing single StringBuilder) works as intended.
char*** valueOut. The caller probabably needs to pass a reference (ref string[] valuesOut). Moreover I don't thinkulongmaps tosize_tuseuint.