簡體   English   中英

使用IntPtr將結構數組從C#傳遞到C ++

[英]passing an array of structures from C# to C++ using IntPtr

我有一個結構->

   public struct readers
   {
       [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1000)]
       public IntPtr[] tag_list;
   };

必須在“ IntPtr [] tag_list”和結構TAG_IN_PARAM之間進行編組

   [StructLayout(LayoutKind.Sequential)]
   internal struct TAG_IN_PARAM
   {
       public int vis_cnt;
       public bool valid;
   }

同樣,它的數組為=> TAG_IN_PARAM [] tag_list =新的TAG_IN_PARAM [1000];

我想將結構“閱讀器”從C#傳遞到C ++ DLL。 但是,我一直在進行編組,但是DLL端的垃圾值不斷增加。

//分配內存Marshal.StructureToPtr(tag_list [j],Reader.tag_list [j],false);

或者,如果我可以通過其他任何方式,請方便。 任何幫助,將不勝感激。 提前致謝。

根據您的評論,您要匹配的C ++類型是:

class Readers 
{
public:
    TAG_IN_PARAM* tag_list;
};

那是指向數組的指針。

但是您的C#代碼聲明了一個內聯數組。 您的C#代碼將與此匹配:

class Readers 
{
public:
    TAG_IN_PARAM tag_list[1000];
};

顯然,這不是您想要的方式。

您需要更改C#代碼以使其匹配。 不幸的是,當數組位於結構內部時,編組器似乎不會將數組作為第一個元素的指針進行封送。 由於數組是結構中的唯一內容,因此您只需將數組作為參數傳遞即可。

另外,如果您絕對需要在結構中傳遞數組,那么我認為您需要手動編組。 像這樣。

public struct readers
{
    public IntPtr tag_list;
};

然后,您可以簡單地固定陣列。

TAG_IN_PARAM[] tag_list = ...;
GCHandle pinnedArray = GCHandle.Alloc(tag_list, GCHandleType.Pinned);
readers r;
r.tag_list = pinnedArray.AddrOfPinnedObject();
// call function passing r
pinnedArray.Free();

不幸的是,由於C# bool不可設置,因此無法正常工作。 因此,您可以通過對該字段使用其他類型來解決此問題。 例如, byteint取決於C ++方面。

每個字段上的另一個選擇是Marshal.StructureToPtr 這樣運行:

TAG_IN_PARAM[] tag_list = ...;
int structSize = Marshal.SizeOf(typeof(TAG_IN_PARAM));
r.tag_list = Marshal.AllocHGlobal(tag_list.Length*structSize);
IntPtr ptr = r.tag_list;
for (int i = 0; i < tag_list.Length; i++)
{
    Marshal.StructureToPtr(tag_list[i], ptr, false);
    ptr += structSize;
    // or on older versions of .net without arithmetic support on IntPtr
    // ptr = (IntPtr) (long)ptr + structSize;
}
// call function passing r
Marshal.FreeHGlobal(r.tag_list);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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