亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從 C# 代碼傳遞到 C 代碼的結構數組

從 C# 代碼傳遞到 C 代碼的結構數組

C#
慕村225694 2022-08-20 17:39:36
我已將一個結構數組從 C#(托管代碼)傳遞到 C(非托管代碼)。結構的內存在 C# 端分配。該數組以 C 代碼填充。我的代碼是多線程的。數組的填充由一個線程完成,另一個線程從結構數組中讀取已填充的項。但是我無法從第二個線程讀取數據,直到第一個線程退出,但是內存由兩個線程共享。示例代碼C# 結構public struct Data{    public IntPtr str;    [MarshalAs(UnmanagedType.I4)]    public int id;}在 C# 端分配結構數組的內存GCHandle[] handles = new GCHandle[10];for (int i = 0; i < 10; i++){     _data[i] = new Data();     byte[] bd = new byte[100];     handles[i] = GCHandle.Alloc(bd, GCHandleType.Pinned);     data[i].str = handles[i].AddrOfPinnedObject();}第一個線程將此結構數組_data傳遞給非托管代碼(C 代碼)以使用 func 進行填充void func([In,Out] Data[] _data);第二個線程開始讀取填充的結構數據,但第一個線程仍在填充靜態索引的數據。在這種情況下,數據可用于但顯示0,但在C端它顯示正確的填充值,即5。請幫助為什么結構成員int id的數據為0。正確的值僅在第一個線程結束后出現。但是,由于內存是共享的,因此,一旦被非托管代碼填充,它必須立即可用。_data[0].str_data[0].id任何幫助將不勝感激。我希望即使線程 1 沒有結束,線程 2 也必須能夠獲取已在非托管代碼中填充的索引值。
查看完整描述

1 回答

?
神不在的星期二

TA貢獻1963條經驗 獲得超6個贊

由于將托管數組傳遞給非托管代碼,因此 clr 會先將該數組復制到另一個內存塊中,然后將其傳遞給非托管函數。非托管函數完成后,clr 會將內存封送回托管數組,然后得到結果。


解決方案是將數組地址直接與不安全代碼一起使用。


extern void func(Data* data);


fixed(Data* p = _data)

{

    func(p);

}

如果您不喜歡不安全的代碼,由于結構數組的內存是順序的,因此您可以傳遞第一個元素的引用。但我不確定這是否足夠安全。


extern void func(ref Data data);


func(ref _data[0]);


查看完整回答
反對 回復 2022-08-20
  • 1 回答
  • 0 關注
  • 151 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號