Как маршалировать структуру как указатель на структуру?
Я пытаюсь передать структуру из C# в библиотеку C++. Я передаю структуру как объект, а функция C++ ожидает ее как указатель (void *).
У меня проблемы с передачей структуры.
[DllImport("MockVadavLib.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr TheFunction([MarshalAs(UnmanagedType.LPStruct)] UserRec userRec);
Вот текст исключения во время выполнения, который я получаю:
"Cannot marshal 'параметр #1': недопустимая комбинация управляемого / неуправляемого типа (этот тип значения должен быть связан со Struct)."
Хотя я нашел статью MSDN, которая использует LPStruct именно в этом контексте.
Это моя структура, которую я пытаюсь маршалировать:
[StructLayout(LayoutKind.Sequential)]
public struct UserRec {
[MarshalAs(UnmanagedType.I4)]
public int userParam1;
}
Это функция C++:
MOCKVADAVLIB_API tVDACQ_CallBackRec * TheFunction(void * userParams) {...
2 ответа
Попробуйте передать структуру в качестве параметра ref.
[DllImport("MockVadavLib.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr TheFunction(ref UserRec userRec);
Когда вы используете ссылку в сочетании со структурой, она концептуально передает адрес.
Между прочим, UnmanagedType.LPStruct
редко, если вообще, правильный MarshalAs
аргумент. Цитата Адама Натана, сотрудника Microsoft:
UnmanagedType.LPStruct поддерживается только для одного конкретного случая: обработка типа значения System.Guid как неуправляемого GUID с дополнительным уровнем косвенности.
Дополнительная информация о посте @Rytmis.
С https://github.com/dotnet/runtime/blob/master/docs/coding-guidelines/interop-pinvokes.md:
Гиды можно использовать непосредственно в подписях. При передаче по ссылке они могут быть переданы по
ref
или с[MarshalAs(UnmanagedType.LPStruct)]
атрибут.
[MarshalAs(UnmanagedType.LPStruct)]
должен использоваться только для ref Guids.