次の C++ 関数定義があり、マネージ コードから PInvoke を介して呼び出そうとしています。
bool FooBar(SIZE_T* arg1);
私のマネージ宣言は次のようになりました。
[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref uint arg1);
一部の人は、私が最終的に行ったのと同じバグに気付くかもしれません。これは 64 ビット ポータブルではありません。SIZE_T は可変サイズ (32 ~ 64 ビット) で、それへのポインタです。管理されたサイズでは、ポインターは 64 ビットに正しく変換されますが、uint は変換されず、arg1 の上位ビットにゴミが残る可能性があります。ゴミ箱はしばしばゼロだったので、これは特に永続的なエラーでした:(
私がうまくいった唯一の解決策は、次のマネージド宣言です。
[DllImport("mydll", SetLastError=true, CharSet=CharSet.Unicode)]
private static extern bool FooBar(ref IntPtr arg1);
IntPtr はそのサイズを正しく変更できるため、これはもちろん機能します。私のコードでは、IntPtr を整数として扱うだけで動作しますが、醜いハックのように見えます。おそらくUnmanagedType.SysUIntを使用して、これを適切に指定する方法があるはずですが、他の有効な解決策を思い付くことができませんでした。