第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

將復(fù)雜的數(shù)據(jù)結(jié)構(gòu)從 C# 傳遞到本機(jī) dll

將復(fù)雜的數(shù)據(jù)結(jié)構(gòu)從 C# 傳遞到本機(jī) dll

C#
HUWWW 2022-07-23 17:59:12
我正在從 NetCore 應(yīng)用程序調(diào)用用 C 編寫的第三方庫(kù)。問(wèn)題是,為了使用這個(gè)庫(kù),我首先需要進(jìn)行調(diào)用并配置一個(gè)復(fù)雜的結(jié)構(gòu),該結(jié)構(gòu)稍后必須傳遞給所有后續(xù)調(diào)用。void createCtx(modbus_t ** ctx){    *ctx = modbus_new_tcp("192.168.1.175", 502);    //configure the context here ....    int res = modbus_connect(*ctx);}int pollData(modbus_t * ctx){    //....    modbus_read_bits(ctx, addr, 1, tab_rp_bits);    //....}我的方法是在調(diào)用者應(yīng)用程序 (C#) 上創(chuàng)建 modbus_t 對(duì)象,通過(guò)調(diào)用 createCtx 對(duì)其進(jìn)行配置,然后定期將其傳遞給 pollData。我已經(jīng)閱讀了有關(guān) StructLayout 的內(nèi)容,但由于我不需要訪問(wèn) modbusContext 對(duì)象中的數(shù)據(jù),我只想為上下文保留一塊內(nèi)存,讓 C# 忘記里面的內(nèi)容。這就是我想出的static IntPtr modbusContext;static class ModbusDriver{            [DllImport("modbusdriver",EntryPoint = "createCtx")]            public static extern void CreateCtx(ref IntPtr modbusContext);            [DllImport("modbusdriver",EntryPoint = "pollData")]            public static extern uint PollData(IntPtr modbusContext)        }        static void Main(string[] args)        {            int ctxSize = ModbusDriver.GetCtxSize();            modbusContext = Marshal.AllocHGlobal(80 * Marshal.SizeOf(typeof(byte))); //<--- 80 is the result of sizeof(modbus_t)            ModbusDriver.CreateCtx(ref modbusContext);            while(true)            {                ModbusDriver.PollData(modbusContext);                Thread.Sleep(1000);            }        }    }這一切似乎都行得通,但感覺(jué)不太對(duì)勁,尤其是因?yàn)?modbus_t 結(jié)構(gòu)相當(dāng)復(fù)雜struct modbus_t {    /* Slave address */    int slave;    /* Socket or file descriptor */    int s;    int debug;    int error_recovery;    struct timeval response_timeout;    struct timeval byte_timeout;    struct timeval indication_timeout;    const modbus_backend_t *backend;    void *backend_data;};所以我的問(wèn)題是,我的方法正確嗎?具體來(lái)說(shuō), modbus_t 包含指針。我設(shè)法在 C# 中保留了 modbus_t 結(jié)構(gòu),它似乎可以工作,但是假設(shè)結(jié)構(gòu)中包含的指針引用的內(nèi)存在調(diào)用之間不會(huì)被破壞真的安全嗎?感覺(jué)不對(duì)。
查看完整描述

1 回答

?
元芳怎么了

TA貢獻(xiàn)1798條經(jīng)驗(yàn) 獲得超7個(gè)贊

只要您不想修改數(shù)據(jù),就可以安全地將數(shù)據(jù)包裝為 void * 或 IntPtr。您通過(guò) AllocHGlobal 分配數(shù)據(jù),后者通過(guò) LocalAlloc 從本地進(jìn)程堆返回?cái)?shù)據(jù),最終調(diào)用 RtlAllocateHeap。對(duì)于 C#,該指針是一個(gè)黑盒子,永遠(yuǎn)不會(huì)寫入或修改它。只要您不提前釋放數(shù)據(jù),一切都會(huì)好起來(lái)的。

C 編程規(guī)則適用:您需要手動(dòng)管理內(nèi)存,并注意誰(shuí)擁有數(shù)據(jù)以及誰(shuí)負(fù)責(zé)刪除它。

只有當(dāng)您嘗試將該指針映射到部分嘗試授予對(duì)某些字段的訪問(wèn)權(quán)限的托管類時(shí),才會(huì)出現(xiàn)問(wèn)題。然后您需要注意結(jié)構(gòu)成員對(duì)齊方式與 C 頭文件中的對(duì)齊方式相同,并且您需要為要跳過(guò)的數(shù)據(jù)獲取正確的偏移量。然后,您可以將 IntPtr 轉(zhuǎn)換為 C# 結(jié)構(gòu),作為帶有不安全代碼的指針,如果您得到正確的偏移量和對(duì)齊,它應(yīng)該可以工作。

如果 C++ 類是包含 STL 數(shù)據(jù)類型的頭文件的一部分,情況就完全不同了。這些東西根本不是可包裝的,因?yàn)槌蓡T對(duì)齊取決于您當(dāng)前編譯器的隨附 STL 版本,這在私有成員字段之間強(qiáng)加了一個(gè)緊密的合同,可以在 C++/STL 版本之間更改。為此,您需要一個(gè) C 包裝器,它將輔助方法包裝為普通的 C 方法,具有內(nèi)部調(diào)用 C++ 方法的常用結(jié)構(gòu)。托管 C++ 是一種相當(dāng)過(guò)時(shí)的技術(shù),不應(yīng)再使用。

總結(jié)一下:您目前的方法很好,并且會(huì)奏效。如果您想從字節(jié) blob 訪問(wèn)修改數(shù)據(jù),這將變得更加工作,但是一旦您知道如何在 C# 中聲明僅包含原始類型(沒(méi)有字符串、字典或指向托管堆結(jié)構(gòu)的指針)的包裝器結(jié)構(gòu),這也是可行的。


查看完整回答
反對(duì) 回復(fù) 2022-07-23
  • 1 回答
  • 0 關(guān)注
  • 210 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)