2013-10-08 25 views
1

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

+1

PInvoke不会给出编译错误,因为关于函数的唯一信息是它的PInvoke声明 - 没有h文件。如果参数类型不同,但参数大小相同,则可能会有效。顺便说一句,你希望在1分钟内回复? –

回答

1

您可以躺在通过在函数[DllImport]声明你的牙齿,很少有该PInvoke的编组可以做检测你的声明是不匹配的。它只知道有一个具有特定名称的DLL文件,该文件用特定名称导出函数。它无法说明该函数需要什么参数,也不知道它返回了什么。这需要更好的函数元数据,即COM类型库或.NET程序集元数据可以提供的类型。没有这样的元数据存在一个普通的DLL,所以它必须假定你的声明是准确的。

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

有意使它完全错误,就像希望DateTime将映射到int一样,如果幸运的话可以通过硬性崩溃来诊断。像AccessViolationException或PInvokeStackImbalance一样。然而,没有这种运气的保证,它只是可能产生垃圾。

1

它不会给你一个编译器错误,因为它不会在编译时发生。编译器在编译时没有关于本地方法和类型的任何信息(除了pinvoke签名),因此不能帮助你。在MSDN状态

大多数PInvoke的帮助页面:

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

如果你想获得更细致和详细理解p/invoke,那么你可以找到大量的文章和博客文章。这里有几个我建议您阅读:

CLR Inside Out: Marshaling between Managed and Unmanaged Code

Calling Win32 DLLs in C# with P/Invoke

P/Invoke Revisited

+0

+1为链接。谢谢 –

相关问题