Я работаю над проектом C#, используя 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
будет < структура href="http://msdn.microsoft.com/en-us/library/windows/desktop/ff800840.aspx" rel="nofollow noreferrer">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
. (Это требуется для членов struct
размера fixed
.)