Как маршалировать структуру как указатель на структуру?

Я пытаюсь передать структуру из 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.

Другие вопросы по тегам