我已声明struct
如下:
// C++
struct TestStruct
{
wchar_t* TestString;
};
和相应的托管代表
// C#
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct TestStruct
{
[MarshalAs(UnmanagedType.LPWStr)]
public string TestString;
}
以及此功能:
// C++
__declspec(dllexport) void __stdcall FillMultipleStructs(TestStruct* testStructures, const short arrayLength)
{
for(int i = 0; i < arrayLength; i++)
{
const wchar_t stringToAllocate[] = L"foo";
const unsigned long size = wcslen(stringToAllocate) * sizeof(wchar_t) + sizeof(wchar_t);
wchar_t* allocatedString = static_cast<wchar_t*>(::CoTaskMemAlloc(size));
wcscpy_s(allocatedString, size, stringToAllocate);
(&testStructures[i])->testString = allocatedString;
}
}
由FillMultipleStructs
方法调用,它需要多个TestStructs
并在C ++代码中初始化它们。
// C#
[DllImport("the path", CallingConvention = CallingConvention.StdCall, EntryPoint = "FillMultipleStructs", ExactSpelling = true, CharSet = CharSet.Unicode)]
[SuppressUnmanagedCodeSecurity]
private static extern void _FillMultipleStructs([In, Out] TestStruct[] structures, [MarshalAs(UnmanagedType.I2)] short arrayLength);
public static IEnumerable<TestStruct> FillMultipleStructs(IEnumerable<TestStruct> structures)
{
TestStruct[] structuresArray = structures.ToArray();
_FillMultipleStructs(structuresArray, (short) structuresArray.Length);
return structuresArray;
}
调用代码的方式如下:
FillMultipleStructs(
new List<TestStruct>()
{
new TestStruct(),
new TestStruct(),
new TestStruct()
});
现在,问题是:有时,代码有效,但有时我会收到a heap has been corrupted
错误。我不明白它来自哪里,也不知道它为什么偶尔起作用,有时它不起作用。
我想这与struct
的字符串成员的编组有关,所以,如果有人能告诉我我的错误在哪里,或者是否有人可以指出我正确的方向或显示我是正确的方法,我很乐意欣赏。
答案 0 :(得分:0)
对于遇到同样问题而遇到这个问题的人来说,总结pstrjds在评论中已经说过的内容:
作为
var allMenuItems = fileMaintenanceToolStripMenuItem.Descendants();
编组,然后代替BSTR
来电, 创建CoTaskMemAlloc
个对象
实际上意味着从
更改BSTR
C#
的定义
struct
到
[MarshalAs(UnmanagedType.LPWStr)]
public string TestString;
而不是使用[MarshalAs(UnmanagedType.BStr)]
public string TestString;
在::CoTaskMemAlloc
中分配字符串,而是需要使用C++
。
我无需更改::SysAllocString
C++
的签名,因为struct
(在我的情况下)最终为BSTR
typedef
}。