# 使用 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\)%E3%80%82)

## 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) 上，无法指定要在特定系统库中调用的动态链接库 (DLL) 名称。如果您尝试对项目外部的任何 DLL 进行 P/Invoke 调用，则将导致运行时出现 DllNotFoundException。因此，可以使用 `__Internal` 关键字代替 DLL 名称，这将使用 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)
