[英]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
不可設置,因此無法正常工作。 因此,您可以通過對該字段使用其他類型來解決此問題。 例如, byte
或int
取決於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.