我的应用程序中有一个P / Invoke调用,该调用通过C ++编写的API(一个.dll文件)与外部硬件进行通信

在我安装了最新的.Net 4.5.1之前,该方法一直有效,并且在不进行任何代码更改的情况下,它现在引发异常:“无法将类型'void'隐式转换为'object'”

我应该检查些什么以使我的应用程序与.Net 4.5.1兼容吗?回滚到以前的框架是我发现使其工作的唯一方法!

[DllImport("TestAPI", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
internal static extern bool OMBOpen(int VID, int PID, int CID,
   StringBuilder description,
   int bufferSize);


C ++中方法的本机声明

TESTAPI_API
bool OMBOpen(int VID,int PID,int IID,char* buffer,int bufferSize);




编辑:

最终,问题根本不在于上面的方法调用本身,而是问题在于将数据从一个指针编组到一个数据结构(请参阅接受的答案),这是David Heffernan wiseley怀疑的代码中的其他地方。

最佳答案

尝试将void方法的结果分配给变量时,引发异常“无法将类型'void'隐式转换为'object'”。虽然这通常是编译器错误,但如果在执行期间看到它,则通常是由于动态调用方法(例如,使用dynamic关键字或使用诸如IronPython之类的动态语言)导致的。

.NET 4.5.1为Marshal.SizeOfMarshal.PtrToStructure引入了重载,在某些情况下,动态方法调用可能会选择新的重载。请参阅Microsoft KB2909958。上面的异常不是来自P / Invoke本身,而是来自随后的封送处​​理操作。

解决这类问题的最简单方法是在调用中引入强制转换,以确保解决了正确的方法。

#Code from 4.5
dynamic dynamicVar = ...
object boxedStruct = Marshal.PtrToStructure(myPtr, dynamicVar.GetType());
// Above resolves to 'object Marshal.PtrToStructure(IntPtr, Type)' in 4.5
// and resolves to 'void Marshal.PtrToStructure<T>(IntPtr, T)' in 4.5.1
int size = Marshal.SizeOf(dynamicVar.GetType());
// Above resolves to 'object Marshal.SizeOf(Type)' in 4.5
// and resolves to 'void Marshal.SizeOf<T>(T)' in 4.5.1

#Fixed for 4.5.1
dynamic dynamicVar = ...
object boxedStruct = Marshal.PtrToStructure(myPtr, (Type)dynamicVar.GetType());
// Adding the cast forces the code to resolve to
// 'object Marshal.PtrToStructure(IntPtr, Type)'
int size = Marshal.SizeOf((Type)dynamicVar.GetType());
// Adding the cast forces the code to resolve to
// 'int Marshal.SizeOf(Type)'

关于c# - P/Invoke方法仅通过从.Net 4.5更新到.Net 4.5.1而中断,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20376324/

10-17 02:40