簡體   English   中英

C# marhsal function 返回指向結構數組的指針

[英]C# marhsal function returning pointer to array of structs

有一個 C++ 庫,其中包含

  • 結構SimpleStruct
  • function 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM