您不能以您可能想到的方式从函数返回数组,但您可以返回指向数组的指针。您还需要返回数组的长度,以便可以正确地将数据编组为适当的 C# 类型。这需要对函数签名稍作更改,以通过传递给函数的参数返回信息。
extern "C" EXPORT_API bool GetCharacterPositions(CharacterInformation** data, int *length)
{
CharacterInformation *characterInformationArray = new CharacterInformation[arraysize];
// initialize contents of array.
// ... snip ...
*length = arraysize;
*data = characterInformationArray;
return true;
}
在这种情况下,您需要添加一个默认构造函数CharacterInformation
并使用两阶段初始化(即Init()
函数)。
请注意,您不应返回指向非静态局部变量的指针或引用,因为变量的内容将在超出范围时(即函数返回时)被销毁。
要编组数据,您可以尝试以下操作。这是未经测试的,但应该可以推动您朝着正确的方向前进。
[DllImport("Dllname.dll",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool GetCharacterPositions(out IntPtr arrayPtr, out int size);
public static List<CharacterInformation> GetCharacterPositions()
{
var arrayValue = IntPtr.Zero;
var size = 0;
var list = new List<CharacterInformation>();
if ( !GetCharacterPositions(out arrayValue, out size))
{
return list;
}
var dataEntrySize = Marshal.SizeOf(typeof(CharacterInformation));
for ( var i = 0; i < size; i++)
{
var cur = (CharacterInformation )Marshal.PtrToStructure(arrayValue, typeof(CharacterInformation ));
list.Add(cur);
arrayValue = new IntPtr(arrayValue.ToInt32() + dataEntrySize);
}
return list;
}
您需要添加一个额外的调用才能正确删除 C++ 中的数据,否则最终会导致内存泄漏。