欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

解讀封送類、結(jié)構(gòu)體和聯(lián)合體實例

 更新時間:2025年01月07日 09:28:16   作者:C6666888  
本文主要介紹了.NETFramework中類、結(jié)構(gòu)體和聯(lián)合體的封送處理,包括類通過COM互操作封送為接口、結(jié)構(gòu)體通過StructLayoutAttribute屬性指定布局和封送方式,以及聯(lián)合體通過StructLayout(LayoutKind.Explicit)和FieldOffset特性精確控制內(nèi)存布局

封送類、結(jié)構(gòu)體和聯(lián)合體實例

封送類

在.NET Framework中,類是引用類型,而結(jié)構(gòu)體是值類型。對于類而言,它們只能通過COM互操作來封送,并且總是作為接口封送。

當托管類傳遞給COM時,互操作封送處理器會自動使用COM代理包裝該類,并將由代理生成的類接口傳遞到COM方法調(diào)用。

例如:

// 假設(shè)有一個非托管的COM接口IDemoInterface
[ComImport]
[Guid("...")]
interface IDemoInterface {
    void DoSomething();
}

// 定義一個實現(xiàn)該接口的托管類
public class ManagedClass : IDemoInterface {
    public void DoSomething() {
        Console.WriteLine("Doing something...");
    }
}

// 在托管代碼中創(chuàng)建并傳遞給非托管代碼
var managedInstance = new ManagedClass();
// 這里假設(shè)有一個非托管函數(shù)接收IDemoInterface類型的參數(shù)
NativeMethods.PassToUnmanaged(managedInstance);

這里PassToUnmanaged是一個平臺調(diào)用(P/Invoke)定義的方法,它負責將ManagedClass對象轉(zhuǎn)換成COM接口指針傳遞給非托管代碼。

封送結(jié)構(gòu)體

結(jié)構(gòu)體作為值類型,在跨平臺調(diào)用時也需要適當?shù)姆馑吞幚怼?/p>

為了確保結(jié)構(gòu)體成員按照預期的方式被解釋,通常會在結(jié)構(gòu)體上應用StructLayoutAttribute屬性來指定布局方式。

考慮如下C++定義的結(jié)構(gòu)體:

typedef struct _MYPERSON {
    char* first;
    char* last;
} MYPERSON, *LP_MYPERSON;

C#封送定義可能是這樣的:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MyPerson {
    [MarshalAs(UnmanagedType.LPStr)]
    public string first;
    [MarshalAs(UnmanagedType.LPStr)]
    public string last;
}

這里使用了StructLayout特性指定了順序布局,并通過MarshalAs特性指定了字符串字段如何被封送。

如果要傳遞此結(jié)構(gòu)體到非托管代碼,則可以像下面這樣操作:

[DllImport("PinvokeLib.dll")]
static extern int TestStructInStruct([In] MyPerson2 person2);

// 構(gòu)建MyPerson實例
var person = new MyPerson { first = "John", last = "Doe" };
// 創(chuàng)建包含person指針的MyPerson2實例
var person2 = new MyPerson2 { person = Marshal.AllocCoTaskMem(Marshal.SizeOf(person)), age = 30 };
// 復制person的內(nèi)容到分配的非托管內(nèi)存
Marshal.StructureToPtr(person, person2.person, false);
try {
    // 調(diào)用非托管函數(shù)
    var result = TestStructInStruct(person2);
} finally {
    // 清理非托管資源
    Marshal.FreeCoTaskMem(person2.person);
}

這段代碼展示了如何安全地管理非托管內(nèi)存,并確保正確地封送結(jié)構(gòu)體給非托管函數(shù)。

封送聯(lián)合體

聯(lián)合體(Union)允許在同一段內(nèi)存空間內(nèi)存儲不同類型的數(shù)據(jù)成員。這意味著任何時候只有一個成員有效。

在C#中表示聯(lián)合體通常涉及到使用StructLayout(LayoutKind.Explicit)特性以及FieldOffset特性來精確控制成員的位置。

比如,我們有以下C++定義的聯(lián)合體:

union MYUNION {
    int i;
    double d;
};

C#封送定義可以是:

[StructLayout(LayoutKind.Explicit)]
public struct MyUnion {
    [FieldOffset(0)]
    public int i;
    [FieldOffset(0)]
    public double d;
}

這里使用了Explicit布局模式,所有字段都從偏移量0開始,意味著它們共享相同的內(nèi)存位置。

當需要傳遞這個聯(lián)合體到非托管代碼時,可以直接使用上述定義,因為.NET運行時知道如何正確地封送聯(lián)合體中的成員。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評論