MarshalAsAttribute

MarshalAsAttributeで、マネージドとアンマネージドの間でデータ変換(マーシャリング)の指示を指定する。

MarshalAsAttribute クラス (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, [MarshalAs(UnmanagedType.LPStr)] string lpText, string lpCaption, uint Type);   // WindowsAPIのMessageBoxAの宣言.

    // メインメソッド
    static void Main()  // Mainメソッドの定義
    {

        // メッセージボックスの表示.
        IntPtr handle = new IntPtr(0);  // IntPtr型handleを生成し, コンストラクタに0をセット.(0なのでnullのウィンドウハンドルを表す.)
        MessageBoxA(handle, "あいうえお", "DllImportAttribute_", 0);    // MessageBoxAで"あいうえお"を表示.

    }

}

UnicodeなのにANSI版関数なので、本来は文字化けするが、MarshalAsでLPStrへのマーシャリング指示だから、

文字化けしない。
文字化けしない。

文字化けしない。

こちらはAnsiなのにUnicode版関数なので、本来は文字化けするが、MarshalAsでLPWStrへのマーシャリング指示だから、

文字化けしない。
文字化けしない。

文字化けしない。

Sample/dotnet/MarshalAsAttribute/MarshalAsAttribute/src/MarshalAsAttribute at master · bg1bgst333/Sample · GitHub]