C#封送類

封送類(Marshaling classes)在.NET框架中扮演著至關重要的角色,尤其是在托管代碼與非托管代碼之間進行數據交換時。封送過程涉及到將托管環境中的對象轉換為非托管環境中可以理解的形式,并且反之亦然。這一過程確保了兩種不同類型的代碼能夠有效地通信和協作。

以下是封送類、結構和聯合

類型描述示例
按值傳遞類將具有整數成員的類傳遞為In/Out參數,與托管的情形相似。SysTime 示例
按值傳遞結構將結構作為In參數傳遞。結構示例
按引用傳遞結構將結構作為In/Out參數傳遞。OSInfo 示例
具有內嵌結構(平展)的結構傳遞非托管函數中表示內嵌結構的結構的類。此結構再托管的原型中將平展為一個的結構。FindFile 示例
具有指向另一結構的指針的結構將包含指向第二結構的指針的結構作為成員傳遞。結構示例
按值傳遞具有整數的結構數組將僅包含整數的結構數組作為In/Out參數進行傳遞。可以更改數組的成員。數組示例
按引用傳遞具有整數和字符串的結構數組將包含整數和字符串的結構數組作為Out參數參數。被調用的函數為數組分配內存。OutArrayOfStructs 示例
具有值類型的聯合傳遞具有值類型(整數和雙精度)的聯合。聯合示例
具有混合類型的聯合傳遞具有混合類型(整數和字符串)的聯合。聯合示例
具有特定平臺的布局的結構使用本機打包的傳遞類型。平臺示例
結構中的null值傳遞空引用(Visual Basic中為Nothing),而不傳遞對值類型的引用。HandleRef 示例

類的封送

當涉及到類的封送時,需要注意的是,在.NET Framework中,類是引用類型,而結構體是值類型。這意味著類實例通過引用傳遞,而結構體則是通過復制整個結構體的內容來傳遞。對于類而言,默認情況下它們只能通過COM互操作來進行封送,并總是作為接口被封送。

對于類而言,默認情況下它們只能通過COM互操作來進行封送,并總是作為接口被封送。具體來說:

  • 向COM傳遞類:當托管類傳遞給COM時,互操作封送處理程序會自動使用COM代理包裝該類,并將由代理生成的類接口傳遞到COM方法調用。代理負責委托對類接口的所有調用返回給托管對象,并公開其他不由類顯式實現的接口,如IUnknownIDispatch

  • 向.NET代碼傳遞類:當接口傳遞回托管代碼時,互操作封送處理程序負責用適當的包裝器包裝接口,并將這個包裝器傳遞給托管方法。每個COM對象實例都有一個唯一的包裝器,無論該對象實現了多少個接口。例如,如果一個COM對象實現了五個不同的接口,則只有一個包裝器實例存在,它公開所有這五個接口。

封送類的默認行為

對于某些特定的.NET類型,如數組、布爾值、字符、委托、類、對象、字符串和結構等,默認的封送規則已經定義好了。這些規則決定了數據如何在托管和非托管內存之間傳遞。例如,.NET數組通常會被封送成指向數組元素本機表示形式的指針;而對于字符串,默認情況下會根據上下文選擇合適的編碼方式(如UTF-16, ANSI, UTF-8等),并且可以通過設置MarshalAs屬性來指定更具體的封送選項。

自定義封送

盡管有默認的封送規則,但在很多實際應用場景下,開發者可能需要更加精細地控制封送過程。這時就可以利用MarshalAsAttribute屬性來指定參數或字段應該怎樣被封送。例如,如果你想要將字符串作為以null結尾的UTF-8字符串發送,你可以這樣做:

[LibraryImport("somenativelibrary.dll")]
static extern int MethodA([MarshalAs(UnmanagedType.LPStr)] string parameter);
//或者
[LibraryImport("somenativelibrary.dll", StringMarshalling = StringMarshalling.Utf8)]
static extern int MethodB(string parameter);

示例:封送具有嵌套結構的類

假設我們有一個C++ DLL導出了一個名為MYPERSON3的結構體,其中包含了另一個結構體MYPERSON以及一個整數成員age。要在C#中正確地封送這樣的結構體,我們可以定義相應的托管結構如下:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MyPerson
{public string first;public string last;
}[StructLayout(LayoutKind.Sequential)]
public struct MyPerson3
{public MyPerson person;public int age;
}

接著,我們需要為非托管函數創建一個托管原型,并確保正確地處理結構體的封送。如果我們知道函數接受的是按值傳遞的MYPERSON3結構體,那么我們的C#聲明可能會像這樣:

private static class NativeMethods
{[DllImport("..\\LIB\\PinvokeLib.dll")]public static extern void TestStructInStruct3(MyPerson3 person3);
}

在這個例子中,MyPerson3結構體會作為一個整體被復制到非托管堆棧上,然后傳遞給非托管函數。如果函數修改了結構體的內容,那么這些更改不會反映回原始的托管副本,除非我們將參數標記為refout,從而允許雙向的數據流動。

總結:

封送類涉及到了解托管與非托管邊界上的數據傳輸機制,包括但不限于上述提到的各種細節。正確地配置和管理這些細節可以幫助避免潛在的問題,確保應用程序之間的互操作性順暢無誤。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/64592.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64592.shtml
英文地址,請注明出處:http://en.pswp.cn/web/64592.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機體系結構期末考試

1、描述計算機系統性能評估的關鍵指標,并以SPEC CPU benchmark為例,討論如何使用幾何平均數與加權平均數對性能進行量化。此外,描述Amdahl定律并分析該定律的應用場景及其對性能優化的局限性 2、請對比RISC和CISC指令集架構的設計思想及優缺點…

藥片缺陷檢測數據集,8625張圖片,使用YOLO,PASICAL VOC XML,COCO JSON格式標注,可識別藥品是否有缺陷,是否完整

藥片缺陷檢測數據集,8625張圖片,使用YOLO,PASICAL VOC XML,COCO JSON格式標注,可識別藥品是否有缺陷,是否完整 有缺陷的標注信息: 無缺陷的標注信息 數據集下載: yolov11:https://d…

一文講清楚CSS3新特性

文章目錄 一文講清楚CSS3新特性1. 新增選擇器特性2. 新增的樣式3. 新增布局方式 一文講清楚CSS3新特性 1. 新增選擇器特性 層次選擇器(div~p)選擇前面有div的p元素偽類選擇器 :first-of-type 表示?組同級元素中其類型的第?個元素:last-of-type 表示?組同級元素中其類型的最…

【Ubuntu使用技巧】Ubuntu22.04無人值守Crontab工具實戰詳解

一個愿意佇立在巨人肩膀上的農民...... Crontab是Linux和類Unix操作系統下的一個任務調度工具,用于周期性地執行指定的任務或命令。Crontab允許用戶創建和管理計劃任務,以便在特定的時間間隔或時間點自動運行命令或腳本。這些任務可以按照分鐘、小時、日…

第十六屆藍橋杯模擬賽(第一期)(C語言)

判斷質因數 如果一個數p是個質數,同時又是整數a的約數,則p稱為a的一個質因數。 請問2024有多少個質因數。 了解 約數,又稱因數。整數a整除整數b,b為a的因數(約數)質數,又稱素數。只有1和它本身兩…

electron在arm64架構交叉編譯遇到libnotify/notify.h文件找不到錯誤記錄

問題描述 在按照官方文檔進行arm64下electron編譯時出現下面的錯誤,編譯環境為ubuntun22.04.5。 問題分析 由于當前目標架構是arm64,所以從上圖可知sysroot為build/linux/debian_bullseye_arm64-sysroot,進入到該目錄下查看libnotify的頭文…

KAFKA入門:原理架構解析

文章目錄 一、認識kafka二、架構介紹2.1 工作流程2.2 Kafka可靠性保證2.3 Kafka存儲 一、認識kafka Kafka到底是個啥?用來干嘛的? 官方定義如下: Kafka is used for building real-time data pipelines and streaming apps. It is horizont…

論文分享 | PromptFuzz:用于模糊測試驅動程序生成的提示模糊測試

大語言模型擁有的強大能力可以用來輔助多種工作,但如何有效的輔助仍然需要人的精巧設計。分享一篇發表于2024年CCS會議的論文PromptFuzz,它利用模型提示生成模糊測試驅動代碼,并將代碼片段嵌入到LLVM框架中執行模糊測試。 論文摘要 制作高質…

利用Python爬蟲獲取1688商品詳情的探索之旅

在當今數字化時代,數據已成為一種寶貴的資源。對于電商行業來說,獲取商品信息尤為重要。阿里巴巴旗下的1688平臺,作為中國領先的B2B電子商務平臺,提供了海量的商品信息。本文將帶你了解如何使用Python爬蟲技術,合法合規…

[算法] [leetcode-1137] 第 N 個泰波那契數

1137 第 N 個泰波那契數簡單 泰波那契序列 Tn 定義如下: T0 0, T1 1, T2 1, 且在 n > 0 的條件下 Tn3 Tn Tn1 Tn2 給你整數 n,請返回第 n 個泰波那契數 Tn 的值。 示例 1: 輸入:n 4 輸出:4 解釋&#x…

macOS上怎么制作條形碼

推薦使用Barcode Flow APP,目前支持iOS、macOS、iPadOS 大家可以在app store里面搜索 支持幾乎所有條形碼的格式 gs128、code128、DataMaxitr等等。 導出和打印都可以。 還支持工具規則自動生成。

位運算與操作符應用

一.二進制與進制轉化 1.概念解析 我們常常能聽見2進制,8進制,16進制這些講法。他們都是數值的不同表達形式。根據不同的進制大小有著不同的權重比例。我們生活中常用的是10進制數,也就是逢10進1,由此推理至其他進制。例如2進制就…

適配器模式概述

大體介紹 適配器模式(Adapter Pattern)是一種結構型設計模式,其核心目的是通過提供一個適配器類來使得原本接口不兼容的類可以一起工作。它通過將一個類的接口轉換成客戶端所期望的接口,使得原本因接口不兼容而無法一起工作的類可…

計算機專業考研 408 學科學習方法

計算機專業考研 408 學科涵蓋數據結構、計算機組成原理、操作系統和計算機網絡四門核心課程,內容多且難度大。但只要掌握科學的學習方法,便能化繁為簡,穩步提升。以下為大家詳細介紹 408 學科的學習方法。 一、基礎夯實階段:全面…

C++ 設計模式:命令模式(Command Pattern)

鏈接:C 設計模式 鏈接:C 設計模式 - 訪問器模式 命令模式(Command Pattern)是一種行為型設計模式,它將請求封裝成一個對象,從而使你可以用不同的請求對客戶進行參數化,對請求排隊或記錄請求日志…

html+css+js網頁設計 美食 美食4個頁面帶js

htmlcssjs網頁設計 美食 美食4個頁面帶js 網頁作品代碼簡單,可使用任意HTML輯軟件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html編輯軟件進行運行及修改編輯等操作)。 獲取源碼 1&#…

swagger,showdoc,apifox,Mock 服務,dubbo,ZooKeeper和dubbo的關系

Swagger、ShowDoc 和 Apifox 之間的區別與優勢 Swagger、ShowDoc 和 Apifox 都是用于 API 文檔管理和測試的工具,但它們各有特色和適用場景。以下是詳細的比較,并附上每個工具的具體用法示例。 1. Swagger 特點與優勢: 廣泛采用: Swagger…

邊沿檢測電路漏檢原因分析

邊沿檢測電路漏檢原因分析 常用結構如下&#xff1a; module edge_detect1( input clk, input signal, output pe, //上升沿 output ne, //下降沿 output de //雙邊沿 );reg reg1;always(posedge clk) beginreg1 < signal; endassign pe (~reg1) & signal; assign…

嵌入式硬件雜談(七)IGBT MOS管 三極管應用場景與區別

引言&#xff1a;在現代嵌入式硬件設計中&#xff0c;開關元件作為電路中的重要組成部分&#xff0c;起著至關重要的作用。三種主要的開關元件——IGBT&#xff08;絕緣柵雙極型晶體管&#xff09;、MOSFET&#xff08;金屬氧化物半導體場效應晶體管&#xff09;和三極管&#…

鴻蒙開發:了解正則表達式

前言 從給出的文本中&#xff0c;按照既定的相關規則&#xff0c;匹配出符合的數據&#xff0c;其中的規則就是正則表達式&#xff0c;使用正則表達式&#xff0c;可以使得我們用簡潔的代碼就能實現一定復雜的邏輯&#xff0c;比如判斷一個郵箱賬號是否符合正常的郵箱賬號&…