【发布时间】:2020-02-27 21:28:50
【问题描述】:
我正在尝试将可写(预分配)字符串数组从 C# 传递到 C++ dll。它因“访问冲突写入位置”而失败。
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;
}
请注意,使用单个字符串(char * 签名并传递单个 StringBuilder)按预期工作。
【问题讨论】:
-
我认为编组器不会为您编组所有内容。您将需要找到一种替代方法
-
如果你想改变原始数组,你必须传递一个指向数组
char*** valueOut的指针。调用者可能需要传递一个引用 (ref string[] valuesOut)。此外,我不认为ulong映射到size_t使用uint。