P/在 C# 中调用本机 C++ dll 并提供不同的类型参数

本文关键字:类型参数 dll C++ 本机 调用 | 更新日期: 2023-09-27 18:34:20

我正在将一些托管C++转换为 c# 代码,这需要我从其他 c++ 项目中的相当多的 dll 中 p/调用函数。当您 p/调用这些函数时,您可以指定与C++函数预期的参数类型不同的参数类型。这是如何运行的?因为这不会给出编译器错误。例如:我的 C# pinvoked 函数在函数需要 int 参数时提供了一个日期时间参数。

P/在 C# 中调用本机 C++ dll 并提供不同的类型参数

你可以在 [DllImport] 声明中咬牙切齿地撒谎,pinvoke 封送器几乎无法检测您的声明是否不匹配。 它所知道的只是有一个具有特定名称的DLL文件,该文件导出具有特定名称的函数。 它无法判断函数采用哪些参数或返回什么。 这需要更好的函数元数据,即 COM 类型库或 .NET 程序集元数据可以提供的那种元数据。 纯 DLL 不存在此类元数据,因此它必须假定您的声明是准确的。

这实际上非常有用,它允许您将 void* 映射到 byte[] 或将 IntPtr 映射到引用类型引用或由 ref 传递的值类型。 您可以编写相同函数的重载。

故意让它完全错误,比如希望日期时间映射到一个整数,如果你幸运的话,可以通过硬崩溃来诊断。 比如 AccessViolationException 或 PInvokeStackImbalance。 然而,不能保证这种运气,它很可能只是产生垃圾。

它不会给你一个编译器错误,因为它不会在编译时发生。编组器在编译时实际上没有任何关于本机方法和类型的信息(除了 pinvoke 签名(,因此无法为您提供帮助。

MSDN 上的大多数 pinvoke 帮助页面都处于以下状态:

P/Invoke 提供很少的编译时错误报告,不是类型安全的

如果你想对p/invoke有一个更细致和详细的理解,那么你可以找到大量的文章和博客文章。以下是我建议您阅读的一些内容:

CLR 由内而外:托管代码和非托管代码之间的封送

处理

使用 P/Invoke 在 C# 中调用 Win32 DLL

P/调用重新审视