LoginSignup
4
1

More than 3 years have passed since last update.

P/Invokeのref(またはout)引数にnullを渡す

Last updated at Posted at 2019-07-22

P/Invokeメソッドでref(またはout)引数がオプションの場合、null値を渡すためにIntPtr版のオーバーロードを追加するのがダルるかったのですが、回避方法を知ったのでメモ。(ただし、unsafeは必要)

詳しくは++C++; // 未確認飛行 C さんの参照渡しとポインターの相互変換を見てください。
っていうかほぼパクリです。

TL;DR

  • C# 7から、参照戻り値が使える。
  • Unsafe.AsRefメソッドで、null値を参照に変えられる。

下記のようなP/Invokeメソッドを考える。

[System.Runtime.InteropServices.DllImport("Kernel32.dll")]
static extern bool GetDiskFreeSpaceEx(
  string lpDirectoryName,
  out ulong lpFreeBytesAvailableToCaller,
  out ulong lpTotalNumberOfBytes,
  out ulong lpTotalNumberOfFreeBytes
);

System.Runtime.CompilerServices.Unsafe パッケージをプロジェクトに追加して、ユーティリティ関数を用意する。

unsafe static ref T NullRef<T>()
{
    return ref Unsafe.AsRef<T>(null);
}

下記の様に呼び出す。

GetDiskFreeSpaceEx("C:", out NullRef<ulong>(), out var lpTotalNumberOfBytes, out NullRef<ulong>());

追記

NuGet Gallery | System.Runtime.CompilerServices.Unsafe 5.0.0から、UnsafeクラスでNullRefメソッドが提供されている。


    public static class Unsafe
    {
        public static ref T NullRef<T>();
    }
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1