ネイティブコードを呼び出す際の警告


マネージコードから、DLLのネイティブコードを呼び出すことを、P/Invoke(Platform Invoke)という。

stringやIntPtrなどはマネージコードとネイティブコードで表現方法が異なるため、CLIによって変換処理が行われる。
このように、異なるシステム間でデータを変換する処理をマーシャリングという。


[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string className, string windowName);
上記のような実装だと、静的解析でいくつか警告が出る。

  • CA1060: P/Invoke を NativeMethods クラスに移動します

DllImport属性を用いて定義したメソッドは、NativeMethodsというクラスに含めるという規則になっているが、含まれていませんという警告。
下記のようにクラス内にNativeMethodsを作り、その中でメソッドを宣言すれば解消する。


class TestClass {

internal static class NativeMethods
{
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string className, string windowName);
}

// 実行時はこうする
IntPtr hwnd = NativeMethods.FindWindow(null, "Test Form");
}

  • CA2101: P/Invoke 文字列引数に対してマーシャリングを指定します

FindWindowの場合、stringがマーシャリングされるが、それが意図した形に変換されないかもしれないという警告。
マーシャリング対象に MarshalAs を明示的に指定して、属性にBestFitMapping=false と ThrowOnUnmappableChar=true を設定すれば解消する。


[DllImport("user32.dll", SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
internal static extern IntPtr FindWindow(
[MarshalAs(UnmanagedType.LPStr)] string className,
[MarshalAs(UnmanagedType.LPStr)] string windowName);