私は次の機能を持っています:
public static extern uint FILES_GetMemoryMapping(
[MarshalAs(UnmanagedType.LPStr)] string pPathFile,
out ushort Size,
[MarshalAs(UnmanagedType.LPStr)] string MapName,
out ushort PacketSize,
ref Mapping oMapping,
out byte PagesPerSector);
私はこれをこのように呼びたいです:
FILES_GetMemoryMapping(MapFile, out size, MapName,
out PacketSize, null, out PagePerSector);
残念ながら、タイプref Mapping
を必要とするフィールドにnull
を渡すことはできません。これを修正したキャストはありません。
助言がありますか?
マッピングは構造であると想定していますか?もしそうなら、異なるシグネチャを持つFILES_GetMemoryMapping()
プロトタイプの2つのバージョンを持つことができます。 null
を渡す2番目のオーバーロードでは、パラメーターをIntPtr
にしてIntPtr.Zero
を使用します
public static extern uint FILES_GetMemoryMapping(
[MarshalAs(UnmanagedType.LPStr)] string pPathFile,
out ushort Size,
[MarshalAs(UnmanagedType.LPStr)] string MapName,
out ushort PacketSize,
IntPtr oMapping,
out byte PagesPerSector);
呼び出し例:
FILES_GetMemoryMapping(MapFile, out size, MapName,
out PacketSize, IntPtr.Zero, out PagePerSector);
マッピングが実際には構造ではなくクラスである場合は、値をnullに設定してから渡します。
null
を渡せない理由は、ref
パラメーターがC#コンパイラーによって特別に処理されるためです。 ref
パラメータはすべて、呼び出す関数に渡すことができる参照である必要があります。 null
を渡したいので、関数が期待する参照を提供していないため、コンパイラーはこれを許可しません。
あなたの唯一の本当の選択肢は、ローカル変数を作成し、それをnull
に設定して渡すことです。コンパイラーはそれ以上のことを許可しません。
1つの方法は、ダミー変数を作成してnullを割り当て、それを渡すことです。
Mapping oMapping = null;
FILES_GetMemoryMapping(MapFile, out size, MapName, out PacketSize, ref oMapping, out PagePerSector);
C#言語7.2以降を使用してnullを許可できるようになりました。単純に、関数パラメーターのref
を次のように置き換えます...
void MyFunc(ref Object obj) { ... }
に...
void MyFunc(in Object obj) { ... }
これにより、アプリケーションで関数を呼び出すときに、null
をパラメーター値として渡すことができます。オブジェクトとネイティブタイプで同じように機能し、ref readonly
と構文的に同等です。
@JaredParの answer は間違いなく正しい回答ですが、another回答:unsafe
コードとポインタ:
_unsafe {
Mapping* nullMapping = null;
FILES_GetMemoryMapping(
MapFile,
out size,
MapName,
out PacketSize,
ref *nullMapping, // wat?
out PagePerSector);
}
_
そのは実行時に失敗するように見えますが、実際には失敗しません。ref
と_*
_はそれぞれキャンセルするためその他、および_ref *nullMapping
_の結果の値はnullポインターです。これはFILES_GetMemoryMapping()
がそのパラメーターに対して受け取るものです。
これはおそらく良い考えではありませんが、可能です。
おそらくそれは理想的な答えではないかもしれませんが、関数を呼び出すときにパラメーターとしてnullを渡す必要がある場合は、nullに設定しようとしている変数の仮パラメーターを省略する関数のオーバーロードを作成することを検討してください。
たとえば、次のような関数があるとします。
public void MyFunction(string x, int y, ref string z) {...};
パラメータzにnullを渡せるようにしたい。代わりに、次のような新しいMyFunction
オーバーロードを作成してみてください。
public void MyFunction(string x, int y) {...};
このアプローチはすべての人のニーズに合うわけではありませんが、別の可能な解決策です。