Open7
C#でネイティブ・相互運用するときの道具箱
P/invokeのライブラリ検索する時のLoadLibraryEx
の動作を制御するDefaultDllImportSearchPaths属性
メソッドまたはassembly
に付与する。
.NET 5以降ではNativeLibrary クラス
が使える。
LoadLibrary
とGetProcAddress
を自分で定義しなくてよい。
.NET Core 3.0以降で、P/invokeのライブラリを検索する時の場所をカスタマイズできるNativeLibrary.SetDllImportResolver(Assembly, DllImportResolver) メソッド
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>());
戻り値がHRESULT
型の関数でマーシャラー側でエラーチェックを行う場合、
[DllImport]
にPreserveSig = false
を付与して戻り値をvoid
とすることができる。