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)

Respuestas a la pregunta(1)

Su respuesta a la pregunta