# P/Invoke の使用

> Learn the rules and limitations of using P/invoke.

P/Invoke は、マネージコードからネイティブコードの構造体、コールバック、および関数にアクセスできる技術です。x86 での P/Invoke 関数用デフォルトの呼び出し規則は、`__stdcall` です。詳細は、\[P/Invoke] についての Microsoft のドキュメント ([https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke](https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke)) を参照してください。

## P/invoke マーシャリングのルール##p/invoke-marshaling-rules

P/Invoke マーシャリングのルールは、[.NET マーシャリング](https://learn.microsoft.com/en-us/dotnet/standard/native-interop/type-marshalling)のルールと同じです。ただし、Unity では以下のタイプはサポートされません。

* AnsiBStr
* Currency
* SAFEARRAY
* IDispatch
* TBStr
* VBByRefStr

## P/Invoke の制限##p/invoke-limitations

ユニバーサル Windows プラットフォーム (UWP) では、特定のシステムライブラリへの P/Invoke に動的リンクライブラリ (DLL) 名を指定することはできません。プロジェクトの外部に存在する DLL に P/Invoke を行なおうとすると、ランタイムに DllNotFoundException が発生します。したがって、DLL 名の代わりに `__Internal` キーワードを使用することで、ランタイムのロード時ではなく、プロジェクトのビルド時に C++ リンカーを使用して関数を解決できます。

```
    [DllImport("__Internal")]
    private static extern int CountLettersInString([MarshalAs(UnmanagedType.LPWStr)]string str);
```

マネージコードで関数の宣言時にエラーが発生すると、ランタイムのエラーではなく、リンカーのエラーが発生します。つまり、ランタイムに動的ロードを行う必要はなく、関数が直接呼び出されるため、P/Invoke 呼び出しのオーバーヘッドが軽減されます。

## 追加リソース##additional-resources

* [P/Invoke に関する Microsoft ドキュメント](https://learn.microsoft.com/en-us/dotnet/standard/native-interop/pinvoke)
* [ネイティブ UWP プラグインの作成](/engine/6000.0/manual/platform-specific/windows-store/uwp-developing/uwp-il2cpp-scripting/uwp-il2cpp-plugins/uwp-native-plugins-author.md)
