我的应用程序中有一个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.SizeOf
和Marshal.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/