PinvokeDeviceIoControl参数我正在使用DeviceIoControlC#项目。我已经为我的签名查阅了相关的Pinvoke.net页面:[DllImport("Kernel32.dll",SetLastError=false,CharSet=CharSet.Auto)]publicstaticexternboolDeviceIoControl(SafeFileHandlehDevice,EIOControlCodeIoControlCode,[MarshalAs(UnmanagedType.AsAny)][In]objectInBuffer,uintnInBufferSize,[MarshalAs(UnmanagedType.AsAny)][Out]objectOutBuffer,uintnOutBufferSize,outuintpBytesReturned,[In]IntPtrOverlapped);我从未见过object和[MarshalAs(UnmanagedType.AsAny)],但MSDN文档听起来很有前途:一种在运行时确定对象类型并将对象编组为该类型的动态类型。该成员仅对平台调用方法有效。我的问题是:使用此签名的“最佳”和/或“正确”方式是什么?例如,IOCTL_STORAGE_QUERY_PROPERTY期望InBuffer是一个STORAGE_PROPERTY_QUERY结构。看起来我应该能够定义结构、创建新实例并将其传递给我的Pinvoke签名:varquery=newSTORAGE_PROPERTY_QUERY{PropertyId=0,QueryType=0};DeviceIoControl(...,查询,Marshal.SizeOf(查询),...);但是,我刚得到一个System.ExecutionEngineException,所以我改为:intcb=Marshal.SizeOf(typeof(...));IntPtrquery=Marshal.AllocHGlobal(cb);...元帅.PtrToStructure(...);Marshal.FreeHGlobal(查询);至少当我调用它时它没有抛出任何异常。这真的很难看,尽管屁股上有巨大的痛苦。编组器不能像我希望的那样处理从我的本地结构复制数据吗?输出数据有时会很棘手,因为它们不是固定大小的结构。我知道marshaller不可能自动处理这个,我可以做HGlobal并在我需要的地方复制业务。额外:这个问题起初看起来很有帮助,但最终只是一个不正确的常量。我不反对使用不安全的结构。(固定大小的结构成员需要这个。)DeviceIoControl非常不友好。但是你可以让它不那么痛苦,你不必自己整理它。您可以利用两点:C#支持方法重载,即使您对声明撒谎,pinvoke编组器也会信任您。这对于已经组织成一堆字节的结构来说是完美的。正是DeviceIoControl()所需要的。所以一般的语句如下:[DllImport("Kernel32.dll",SetLastError=true)]publicstaticexternboolDeviceIoControl(SafeFileHandlehDevice,intIoControlCode,byte[]InBuffer,intnInBufferSize,byte[]OutBuffer,intnOutBufferSize,输出intpBytesReturned,IntPtrOverlapped);并且你会添加一个非常适合IOCTL_STORAGE_QUERY_PROPERTY的重载,假设你对它返回STORAGE_DEVICE_DESCRIPTOR感兴趣:STORAGE_PROPERTY_QUERYInBuffer,intnInBufferSize,outSTORAGE_DEVICE_DESCRIPTOROutBuffer,intnOutBufferSize,outintpBytesReturned,IntPtrOverlapped);你会这样称呼它:varquery=newSTORAGE_PROPERTY_QUERY{PropertyId=0,QueryType=0};varqsize=元帅。大小(查询);STORAGE_DEVICE_DESCRIPTOR结果;varrsize=Marshal.SizeOf(结果);int写的;boolok=DeviceIoControl(handle,EIOControlCode.QueryProperty,refquery,qsize,outresult,rsize,写出来,IntPtr.Zero);如果(!ok)抛出新的Win32Exception();if(written!=rsize)thrownewInvalidOperationException("Badstructuredeclaration");它应该看起来比你得到的更漂亮,更可诊断未经测试,应该接近。以上就是C#学习教程:PinvokeDeviceIoControl参数分享的全部内容。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
