【发布时间】:2014-07-18 11:27:47
【问题描述】:
我有一些非托管 C++ 动态库和 C# GUI 应用程序,正在使用它。我需要将已知大小的字符串数组传递给填充它的 C++ 库。还有最大字符串长度值:
// C++ part
#define MAX_SOME_STRING_LEN 250;
MYDLL_API uint8_t __stdcall getSomeStrings(wchar_t** strings, uint64_t count) {
/// populate strings, not more characters then MAX_SOME_STRING_LEN for each string
return 0;
}
// C# part
[DllImport("biosec_lib.dll", CallingConvention = CallingConvention.StdCall)]
static extern Byte getSomeStrings(string[] providers, UInt64 size);
我想避免在 C++ 库端进行数组内存管理。我通过其他库 API 调用获得了理想的字符串数组大小。然后在C#端分配合适的数组,调用这个API方法,传递合适的数组。
- 这是一种好方法吗?有没有更好的方法?在将数组中的每个字符串传递给 API 方法之前,我可以为其保留 MAX_SOME_STRING_LEN 大小吗?
【问题讨论】:
-
问题不在于数组,C#代码已经分配了它。问题是数组elements。你是如何创造它们的?他们需要被释放吗?如果要使用 C# 程序分配的内存,则需要使用 StringBuilder[],并使用具有足够容量的 StringBuilder 对象进行初始化。这是有风险的,当您的 wcscpy() 调用溢出缓冲区时,容量太低会导致堆损坏。
-
@HansPassant 是的,我想分配它们并稍后在 C# 端发布。你提到过,我知道溢出的问题。我应该小心它,并为此提供了缓冲区大小。
-
没有。 count 参数表示 strings 数组的长度。调用者无法指定每个字符串缓冲区的长度。编写此代码的唯一真正安全的方法是让 C++ 代码分配字符串。这确实需要您处理内存管理,调用者必须再次释放字符串。 pinvoke marshaller 会假设你使用了 CoTaskMemAlloc(),如果你没有使用 kaboom。
标签: c# c++ marshalling