C# P/Invoke方法仅通过从.Net 4.5更新到.Net 4.5.1而被破坏

C# P/Invoke方法仅通过从.Net 4.5更新到.Net 4.5.1而被破坏,c#,.net,pinvoke,.net-4.5,C#,.net,Pinvoke,.net 4.5,我的应用程序中有一个p/Invoke调用,它通过用C编写的API(一个.dll文件)与外部硬件进行通信++ 在我安装了最新的.Net 4.5.1之前,这个方法一直工作得很好,在不做任何代码更改的情况下,它现在抛出了一个异常:“无法隐式地将类型'void'转换为'object'” 有什么我应该检查,使我的应用程序与.Net 4.5.1兼容吗?回滚到以前的框架是我找到的使其工作的唯一方法 [DllImport("TestAPI", CharSet = CharSet.Ansi, CallingCon

我的应用程序中有一个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所怀疑的,这是代码中的其他地方

我能发现问题中代码的唯一错误是返回值。默认情况下,封送拆收器将假定本机代码返回一个4字节的
BOOL
。你应该这样写pinvoke:

[DllImport(...)]
[return: MarshalAs(UnmanagedType.I1)]
internal static extern bool OMBOpen(...);
但是,我不认为这会导致您报告的错误。我相当怀疑实际的问题在于不在问题中的代码

参考文献:


  • 我能发现问题中代码的唯一错误是返回值。默认情况下,封送拆收器将假定本机代码返回一个4字节的
    BOOL
    。你应该这样写pinvoke:

    [DllImport(...)]
    [return: MarshalAs(UnmanagedType.I1)]
    internal static extern bool OMBOpen(...);
    
    但是,我不认为这会导致您报告的错误。我相当怀疑实际的问题在于不在问题中的代码

    参考文献:

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

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

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

    #来自4.5的代码
    动态动态var=。。。
    object boxedStruct=Marshal.PtrToStructure(myPtr,dynamicVar.GetType());
    //上面解析为4.5中的“object Marshal.PtrToStructure(IntPtr,Type)”
    //并在4.5.1中解析为“void Marshal.PtrToStructure(IntPtr,T)”
    int size=Marshal.SizeOf(dynamicVar.GetType());
    //以上解析为4.5中的“object Marshal.SizeOf(Type)”
    //并在第4.5.1条中决定“作废封送官的大小(T)”
    #固定为4.5.1
    动态动态var=。。。
    object boxedStruct=Marshal.PtrToStructure(myPtr,(Type)dynamicVar.GetType());
    //添加强制转换将强制代码解析为
    //'对象封送处理.ptr结构(IntPtr,类型)'
    int size=Marshal.SizeOf((Type)dynamicVar.GetType());
    //添加强制转换将强制代码解析为
    //'int Marshal.SizeOf(类型)'
    
    尝试将void方法的结果赋给变量时引发异常“无法将类型'void'隐式转换为'object'”。虽然这通常是一个编译器错误,但如果在执行过程中看到,则通常是由于方法的动态调用(例如,使用dynamic关键字或使用IronPython之类的动态语言)导致的

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

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

    #来自4.5的代码
    动态动态var=。。。
    object boxedStruct=Marshal.PtrToStructure(myPtr,dynamicVar.GetType());
    //上面解析为4.5中的“object Marshal.PtrToStructure(IntPtr,Type)”
    //并在4.5.1中解析为“void Marshal.PtrToStructure(IntPtr,T)”
    int size=Marshal.SizeOf(dynamicVar.GetType());
    //以上解析为4.5中的“object Marshal.SizeOf(Type)”
    //并在第4.5.1条中决定“作废封送官的大小(T)”
    #固定为4.5.1
    动态动态var=。。。
    object boxedStruct=Marshal.PtrToStructure(myPtr,(Type)dynamicVar.GetType());
    //添加强制转换将强制代码解析为
    //'对象封送处理.ptr结构(IntPtr,类型)'
    int size=Marshal.SizeOf((Type)dynamicVar.GetType());
    //添加强制转换将强制代码解析为
    //'int Marshal.SizeOf(类型)'
    
    尝试“TestAPI.dll”而不是“TestAPI”@thefiloe不高兴,但谢谢..您能显示函数的本机声明吗?
    无法隐式地将类型“void”转换为“object”“
    这不是运行时错误,而是编译器错误消息。我来自Microsoft.NET Framework团队。您能给我发送在.NET4.5上工作但在.NET4.5.1上不工作的详细复制代码吗?我想调查一下。将其发送到Microsoft com的netfx45compat上,谢谢!请尝试“TestAPI.dll”而不是“TestAPI”@thefiloe不高兴,但谢谢..您能显示函数的本机声明吗?
    无法隐式地将类型“void”转换为“object”“
    这不是运行时错误,而是编译器错误消息。我来自Microsoft.NET Framework团队。您能给我发送在.NET4.5上工作但在.NET4.5.1上不工作的详细复制代码吗?我想调查一下。将其发送到Microsoft com的netfx45compat上,谢谢!解决了我的问题,非常高兴