.NET(C#)平台叫用:DllImportAttribute.CharSet和字串封送編碼

來源:互聯網
上載者:User

首先如果您看下面代碼有些費解的話,推薦先閱讀以下MSDN上關於平台叫用的指定字元集文章:http://msdn.microsoft.com/zh-cn/library/7b93s42f.aspx

 

學習.NET(C#)的平台叫用和對象封送,你會發現其實同樣的系統API函數的平台叫用定義可以有多種形式的,本文就拿WinAPI的MessageBox開涮。

首先通過DllImportAttribute.CharSet來自動指定名稱探索(根據DllImportAttribute.ExactSpelling)和字串封送,比如,這三個函數的平台叫用最常用定義(來自上面MSDN的頁面)

 

第一個是MessageBox的ANSI函數(MessageBoxA),而DllImportAttribute得CharSet欄位預設值就是CharSet.Ansi枚舉值。

第二個是MessageBox的Unicode函數(MessageBoxW)。

最後一個MessageBox使用自動覺察字元集編碼,NT系統會調用MessageBoxW(Unicode),而98會調用MessageBoxA(ANSI)。

[DllImport("user32.dll")]

public static extern int MessageBoxA(int hWnd, String text, String caption, uint type);

[DllImport("user32.dll", CharSet = CharSet.Unicode)]

public static extern int MessageBoxW(int hWnd, String text, String caption, uint type);

[DllImport("user32.dll", CharSet = CharSet.Auto)]

public static extern int MessageBox(int hWnd, String text, String caption, uint type);

//98調用MessageBoxA, NT調用MessageBoxW

 

接下來把CharSet全部去掉(值預設是CharSet.Ansi)。

然後為了使Unicode的MessageBox工作,手動加入MarshalAs特性把字串封送成UnmanagedType.LPWStr(Unicode字串)。

而最後的MessageBox實際上只會調用MessageBoxA(ANSI的MessageBox函數),因為DllImportAttribute.ExactSpelling會根據CharSet去搜尋,而這裡CharSet是Ansi(後面的Unicode也類似)。

//預設都是CharSet.Ansi

 

[DllImport("user32.dll")]

public static extern int MessageBoxA(int hWnd, String text, String caption, uint type);

 

//手動通過MarshalAs特性把字串以Unicode形式封送

[DllImport("user32.dll")]

public static extern int MessageBoxW(int hWnd,

    [MarshalAs(UnmanagedType.LPWStr)] String text,

    [MarshalAs(UnmanagedType.LPWStr)]String caption,

    uint type);

 

[DllImport("user32.dll")]

public static extern int MessageBox(int hWnd, String text, String caption, uint type);

//調用MessageBoxA

 

如果把CharSet全部改成Unicode,結果則是和上面相反。需要用MarshalAs特性特殊照顧一下MessageBoxA,而最後的MessageBox也只會調用MessageBoxW函數的。

//手動通過MarshalAs特性把字串以ANSI形式封送

[DllImport("user32.dll", CharSet = CharSet.Unicode)]

public static extern int MessageBoxA(int hWnd,

    [MarshalAs(UnmanagedType.LPStr)]String text,

    [MarshalAs(UnmanagedType.LPStr)]String caption,

    uint type);

 

[DllImport("user32.dll", CharSet = CharSet.Unicode)]

public static extern int MessageBoxW(int hWnd, String text, String caption, uint type);

 

[DllImport("user32.dll", CharSet = CharSet.Unicode)]

public static extern int MessageBox(int hWnd, String text, String caption, uint type);

//調用MessageBoxW

 

最後如果CharSet全部是Auto,那麼為了確保所有函數能正常工作,必須為MessageBox的ANSI和Unicode編碼都添加MarshalAs,因為此時字串的封送形式是不定的,當然如果你確定程式會在某個特定的編碼環境中運行,那麼其對應的定義可以省略。最後MessageBox的TCHAR定義和最上面的一樣,即98調用MessageBoxA, NT調用MessageBoxW。

//MarshalAs可以省略如果是98系統

[DllImport("user32.dll", CharSet = CharSet.Auto)]

public static extern int MessageBoxA(int hWnd,

    [MarshalAs(UnmanagedType.LPStr)]String text,

    [MarshalAs(UnmanagedType.LPStr)]String caption,

    uint type);

 

//MarshalAs可以省略如果是NT系統

[DllImport("user32.dll", CharSet = CharSet.Auto)]

public static extern int MessageBoxW(int hWnd,

    [MarshalAs(UnmanagedType.LPWStr)]String text,

    [MarshalAs(UnmanagedType.LPWStr)]String caption, uint type);

 

[DllImport("user32.dll", CharSet = CharSet.Auto)]

public static extern int MessageBox(int hWnd, String text, String caption, uint type);

//98調用MessageBoxA, NT調用MessageBoxW

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.