[英]C# marhsal function returning pointer to array of structs
有一個 C++ 庫,其中包含
SimpleStruct
GetSimpleStructs
返回指向此結構數組的指針像這樣:
typedef struct {
int value1;
int value2;
int value3;
} SimpleStruct;
extern SimpleStruct *GetSimpleStructs(int *count);
我在 C#.Net Core 項目中有這個實現:
[StructLayout(LayoutKind.Sequential)]
struct SimpleStruct
{
int value1;
int value2;
int value3;
}
[DllImport(LibName)]
public static extern IntPtr GetSimpleStructs(out int count);
以及將IntPtr
轉換為SimpleStruct[]
的 function :
SimpleStruct[] GetSimpleStructs()
{
var ptrToArray = GetSimpleStructs(out var count);
var arrayOfPtrs = new IntPtr[count];
var resultArray = new SimpleStruct[count];
Marshal.Copy(ptrToArray, arrayOfPtrs, 0, count);
for (var i = 0; i < count; i++)
resultArray[i] = Marshal.PtrToStructure<SimpleStruct>(arrayOfPtrs[i]); // HERE
return resultArray;
}
在// HERE
行之前一切正常。 在第一次迭代中,程序僅以退出代碼 139 結束,沒有任何異常。
那么我做錯了什么?
另外,我沒有能力在使用DllImport
的項目中使用 struct 引用項目
如果您的非托管方法返回指向結構塊的指針,則不需要IntPtr[]
步驟 -只有一個指針(如果您返回SimpleStruct **
,這將很有用)。
相反,您需要首先確保布局完全正確(包括大小),通過使用顯式布局屬性,然后:只需 go 通過指針:
unsafe
{
SomeStruct* ptr = (SomeStruct*)ptrToArray.ToPointer();
var resultArray = new SimpleStruct[count];
for (int i = 0 ; i < resultArray.Length ; i++)
resultArray[i] = *ptr[i];
}
如果您樂於使用跨度,這可能會更容易。 復制步驟只是:
var resultArray = new Span<SomeStruct>(
ptrToArray.ToPointer(), count).ToArray();
實際上,您可以只返回Span<SomeStruct>
或Memory<SomeStruct>
(后者需要一個額外的步驟,但可能),以允許安全的 C# 代碼直接從非托管 memory 位置訪問數據,而無需將其復制到托管memory 或分配數組!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.