Я работаю над проектом С#, используя DeviceIoControl
. Я просил связать страницу Pinvoke.net для моей подписи:
[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
);
Я раньше не видел object
и [MarshalAs(
UnmanagedType.AsAny
)]
, но Документация MSDN выглядела многообещающе:
Динамический тип, определяющий тип объекта во время выполнения и маршалирует объект как этот тип. Этот член действителен только для методов вызова платформы.
Мой вопрос: что такое "лучший" и/или "правильный" способ использования этой подписи?
Например, IOCTL_STORAGE_QUERY_PROPERTY
ожидает, что InBuffer
будет STORAGE_PROPERTY_QUERY
. Похоже, я должен был бы определить эту структуру, создать экземпляр new
и передать его моей подписке Pinvoke:
var query = new STORAGE_PROPERTY_QUERY { PropertyId = 0, QueryType = 0 };
DeviceIoControl(..., query, Marshal.SizeOf(query), ...);
Тем не менее, я просто сделал System.ExecutionEngineException
, так что я изменил на что-то вроде:
int cb = Marshal.SizeOf(typeof(...));
IntPtr query = Marshal.AllocHGlobal(cb);
...
Marshal.PtrToStructure(...);
Marshal.FreeHGlobal(query);
и он, по крайней мере, не выдавал никаких исключений, когда я его вызывал. Это просто очень уродливо, и огромная боль в прикладе. Не удается ли маршаллеру копировать данные в/из моих локальных структур, как я надеялся?
Выходные данные иногда могут быть сложными, поскольку они не являются структурами фиксированного размера. Я понимаю, что маршаллер не может справиться с этим автоматически, и я в порядке с HGlobal и копией бизнеса, где мне нужно.
Дополнительно:
Этот вопрос сначала выглядел полезным, но он оказался просто неправильной константой.
Я не против использования конструкций unsafe
. (Члены fixed
-size struct
требуют этого.)