Parámetros de Pinvoke DeviceIoControl
Estoy trabajando en un proyecto de C # usandoDeviceIoControl
. He consultado lo relacionado.Página de Pinvoke.net para mi firma:
[DllImport("Kernel32.dll", SetLastError = false, CharSet = CharSet.Auto)]
public static extern bool DeviceIoControl(
SafeFileHandle hDevice,
EIOControlCode IoControlCode,
[MarshalAs(UnmanagedType.AsAny)]
[In] object InBuffer,
uint nInBufferSize,
[MarshalAs(UnmanagedType.AsAny)]
[Out] object OutBuffer,
uint nOutBufferSize,
out uint pBytesReturned,
[In] IntPtr Overlapped
);
Nunca había vistoobject
y[MarshalAs(
UnmanagedType.AsAny
)]
antes, pero elDocumentación de MSDN sonaba prometedor
Un tipo dinámico que determina el tipo de un objeto en tiempo de ejecución y calcula el objeto como ese tipo. Este miembro es válido solo para los métodos de invocación de plataforma.
Mi pregunta es: ¿Cuál es la forma "mejor" y / o "adecuada" de usar esta firma?
Por ejemplo,IOCTL_STORAGE_QUERY_PROPERTY
esperaInBuffer
ser unSTORAGE_PROPERTY_QUERY
estructura. Parece que debería ser capaz de definir esa estructura, crear unanew
instancia, y pasarlo a mi firma Pinvoke:
var query = new STORAGE_PROPERTY_QUERY { PropertyId = 0, QueryType = 0 };
DeviceIoControl(..., query, Marshal.SizeOf(query), ...);
Sin embargo, acabo de recibir unSystem.ExecutionEngineException
haciendo eso, así que cambié a algo como:
int cb = Marshal.SizeOf(typeof(...));
IntPtr query = Marshal.AllocHGlobal(cb);
...
Marshal.PtrToStructure(...);
Marshal.FreeHGlobal(query);
y al menos no lanzó ninguna excepción cuando lo llamé. Eso es muy feo, y un gran dolor en el trasero. ¿No puede el agente de control manejar la copia de datos a / desde mis estructuras locales como esperaba?
Los datos de salida a veces pueden ser complicados, porque no son estructuras de tamaño fijo. Entiendo que el agente de distribución no puede manejar eso automáticamente, y estoy de acuerdo con hacer el HGlobal y copiar el negocio donde lo necesito.
Adicional:
Esta pregunta Parecía útil al principio, pero terminó siendo una constante incorrecta.
No estoy en contra de usarunsafe
construye (Losfixed
-tamañostruct
los miembros requieren esto)