C#からのP/Invokeにおけるパラメータの方向属性*1についてメモ。
C#における既定の方向属性は下表のとおり。呼び出し元/呼び出し先はマネージド(C#)/アンマネージド(native)いずれかになる。つまりexternメソッド呼び出しであればC#→nativeとなり、アンマネージ関数ポインタからのC#デリゲート呼び出しであればnative→C#となる。
C#パラメータ | 既定値 | 効果 |
---|---|---|
(修飾なし) | [In] | 呼び出すとき(前)に引数データをマーシャリング |
out修飾 | [Out] | 呼び出し先から戻るときに引数データをマーシャリング |
ref修飾 | [In,Out] | 上記2つを両方とも適用する |
StringBuilder | [In,Out] | (StringBuilderはCLRマーシャラから特殊扱い)*2 |
ref修飾パラメータの既定値はIn,Out属性となっているため、参照渡しするC#構造体(値型)が呼び出し先で変更されないと分かっている場合は、該当パラメータに対してIn属性を明示指定する方が実行効率が良い。もしくは、既定でIn属性かつ参照渡しが行われるC#クラス(参照型)を使用する。
// native.dll // void WINAPI SetSomeInfo(const SomeStruct *ps); struct SomeStruct { ... } [DllImport("native.dll")] extern void SetSomeInfo([In] ref SomeStruct s); // または class SomeStruct { ... } [DllImport("native.dll")] extern void SetSomeInfo(SomeStruct s);
関連URL