字串的封送處理

iDotNetSpace發表於2008-09-23

  System.String System.StringBuilder 類都有相似的封送處理行為。它們之間的主要差異是字串是不可變的,而 StringBuilder 緩衝區的內容則可以由被呼叫方更改並複製回撥用方。

本主題提供下列有關封送字串型別的資訊:

·                 類庫中使用的字串

·                 平臺呼叫中使用的字串

·                 結構中使用的字串

·                 定長字串緩衝區

類庫中使用的字串

下表顯示字串資料型別被作為方法引數封送到非託管程式碼時的封送處理選項。MarshalAsAttribute 屬性提供了若干個 UnmanagedType 列舉值,以便將字串封送到 COM 介面。

 

列舉型別

非託管格式的說明

UnmanagedType.BStr(預設)

具有預設長度和 Unicode 字元的 COM 樣式的 BSTR

UnmanagedType.LPStr

指向 ANSI 字元的空終止陣列的指標。

UnmanagedType.LPWStr

指向 Unicode 字元的空終止陣列的指標。

 

下面的示例顯示 IStringWorker 介面中宣告的字串。

下面的示例顯示在型別庫中描述的對應介面。

interface IStringWorker : IDispatch {

HRESULT PassString1([in] BSTR s);

HRESULT PassString2([in] BSTR s);

HRESULT PassString3([in] LPStr s);

HRESULT PassString4([in] LPWStr s);

HRESULT PassStringRef1([in, out] BSTR *s);

HRESULT PassStringRef2([in, out] BSTR *s);

HRESULT PassStringRef3([in, out] LPStr *s);

HRESULT PassStringRef4([in, out] LPWStr *s);

);

 

平臺呼叫中使用的字串

平臺呼叫複製字串引數,並從 .NET Framework 格式 (Unicode) 轉換為平臺非託管格式。字串是不可變的,在呼叫返回時不會從非託管記憶體複製回託管記憶體。

下表列出了在字串被作為對平臺呼叫進行的呼叫的方法引數封送時的封送處理選項。MarshalAsAttribute 屬性提供了若干個 UnmanagedType 列舉值以封送字串。

 

列舉型別

非託管格式的說明

UnmanagedType.AnsiBStr

具有預設長度幷包含 ANSI 字元的 COM 樣式 BSTR

UnmanagedType.BStr(預設)

具有預設長度和 Unicode 字元的 COM 樣式的 BSTR

UnmanagedType.LPStr

指向 ANSI 字元的空終止陣列的指標。

UnmanagedType.LPTStr

指向平臺相關的字元的空終止陣列的指標。

UnmanagedType.LPWStr

指向 Unicode 字元的空終止陣列的指標。

UnmanagedType.TBStr

具有預設長度幷包含平臺相關字元的 COM 樣式 BSTR

 

下面的型別定義針對平臺呼叫的呼叫顯示 MarshalAsAttribute 的正確用法。

 

class StringLibAPI {

[DllImport("StringLib.Dll")]

public static extern void PassLPStr([MarshalAs(UnmanagedType.LPStr)] String s);

[DllImport("StringLib.Dll")]

public static extern void

PassLPWStr([MarshalAs(UnmanagedType.LPWStr)]String s);

[DllImport("StringLib.Dll")]

public static extern void

PassLPTStr([MarshalAs(UnmanagedType.LPTStr)]String s);

[DllImport("StringLib.Dll")]

public static extern void PassBStr([MarshalAs(UnmanagedType.BStr)]

String s);

[DllImport("StringLib.Dll")]

public static extern void

PassAnsiBStr([MarshalAs(UnmanagedType.AnsiBStr)]String s);

[DllImport("StringLib.Dll")]

public static extern void PassTBStr([MarshalAs(UnmanagedType.TBStr)]

String s);

}

結構中使用的字串

  字串是結構的有效成員;但是,StringBuilder 緩衝區在結構中是無效的。下表顯示當字串資料型別被作為欄位封送時該型別的封送處理選項。MarshalAsAttribute 屬性提供了若干個 UnmanagedType 列舉值,以便將字串封送到欄位。

 

列舉型別

非託管格式的說明

UnmanagedType.BStr

具有預設長度和 Unicode 字元的 COM 樣式的 BSTR

UnmanagedType.LPStr

指向 ANSI 字元的空終止陣列的指標。

UnmanagedType.LPTStr

指向平臺相關的字元的空終止陣列的指標。

UnmanagedType.LPWStr

指向 Unicode 字元的空終止陣列的指標。

UnmanagedType.ByValTStr

定長的字元陣列;陣列的型別由包含陣列的結構的字符集確定。

 

   ByValTStr 型別用於出現在結構內的內聯的定長字元陣列。其他型別應用於包含指向字串的指標的結構內所包含的字串引用。

應用於包含結構的 StructLayoutAttribute 屬性的 CharSet 引數確定結構中字串的字元格式。下面的示例結構包含字串引用和內聯字串,以及 ANSIUnicode 和平臺相關字元。

型別庫表示形式

struct StringInfoA {

   char *    f1;

   char      f2[256];

};

struct StringInfoW {

   WCHAR *   f1;

   WCHAR     f2[256];

   BSTR      f3;

};

struct StringInfoT {

   TCHAR *   f1;

   TCHAR     f2[256];

};

 

下面的程式碼示例顯示如何使用 MarshalAsAttribute 屬性以不同格式定義同一結構。

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]

struct StringInfoA {

   [MarshalAs(UnmanagedType.LPStr)] public String f1;

   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public String f2;

}

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]

struct StringInfoW {

   [MarshalAs(UnmanagedType.LPWStr)] public String f1;

   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public String f2;

   [MarshalAs(UnmanagedType.BStr)] public String f3;

}

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)]

struct StringInfoT {

   [MarshalAs(UnmanagedType.LPTStr)] public String f1;

   [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)] public String f2;

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/12639172/viewspace-462654/,如需轉載,請註明出處,否則將追究法律責任。

上一篇: input型別和限制
字串的封送處理
請登入後發表評論 登入
全部評論

相關文章