DllImportAttribute.CharSetで、文字列をどのように渡すか、どの関数が呼ばれるかが決まる。
DllImportAttribute.CharSet フィールド (System.Runtime.InteropServices) | Microsoft Learn
例えば、
// 名前空間の登録 using System; // 共通データ型と基本クラス(System名前空間) using System.Runtime.InteropServices; // COM相互運用とプラットフォーム呼び出し(System.Runtime.InteropServices名前空間) // メインクラス class MainClass // MainClassクラスの定義 { // DLLのインポート [DllImport("user32.dll", CharSet = CharSet.Unicode)] // DllImportで"user32.dll"のインポート.(CharSet.Unicodeにする.) public static extern int MessageBoxA(IntPtr hWnd, string lpText, string lpCaption, uint Type); // WindowsAPIのMessageBoxAの宣言. // メインメソッド static void Main() // Mainメソッドの定義 { // メッセージボックスの表示 MessageBoxA((IntPtr)0, "あいうえお", "DllImportAttribute_", 0); // MessageBoxAで"あいうえお"を表示. } }
これだと、Unicode文字列を渡そうとするが、ANSI版のMessageBoxAなので、
このように文字化けする。
// 名前空間の登録 using System; // 共通データ型と基本クラス(System名前空間) using System.Runtime.InteropServices; // COM相互運用とプラットフォーム呼び出し(System.Runtime.InteropServices名前空間) // メインクラス class MainClass // MainClassクラスの定義 { // DLLのインポート [DllImport("user32.dll", CharSet = CharSet.Ansi)] // DllImportで"user32.dll"のインポート.(CharSet.Ansiにする.) public static extern int MessageBoxW(IntPtr hWnd, string lpText, string lpCaption, uint Type); // WindowsAPIのMessageBoxWの宣言. // メインメソッド static void Main() // Mainメソッドの定義 { // メッセージボックスの表示 MessageBoxW((IntPtr)0, "あいうえお", "DllImportAttribute_", 0); // MessageBoxWで"あいうえお"を表示. } }
逆に、ANSI文字列を渡そうとするが、Unicode版のMessageBoxWなので、
こうなったりもする。
Windowsでは、CharSet.AutoはUnicode、CharSet.NoneはANSIらしい。
デフォルトではANSIらしい。
両対応のMessageBoxにしておけば、CharSetによって切り替わるようになる。
CharSet.Autoは、CharSet.Unicodeでもあるので、MessageBoxWが呼ばれる。
CharSet.Noneだと、CharSet.Ansiと同じで、MessageBoxAが呼ばれる。
両対応のMessageBoxならどんなCharSetでも文字化けしない。
切り替わるからね。