Я пишу обертку C# для родной библиотеки. Она содержит эту функцию обратного вызова:C# native callback с указателем на параметр struct
typedef application_event_result(*application_event_ptr)(application_request* request);
Параметр определяется как, например:
typedef struct {
uint32_t query;
const char* client;
bool isAuthenticated;
bool isGuest;
} application_request;
я определил C# обратного вызова делегата, как это:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate application_event_result application_event([MarshalAs(UnmanagedType.Struct)]
ref application_request request);
Структура в C#:
[StructLayout(LayoutKind.Sequential)]
public struct application_request
{
public UInt32 query;
[MarshalAs(UnmanagedType.LPStr)]
public string client;
[MarshalAs(UnmanagedType.I1)]
public bool isAuthenticated;
[MarshalAs(UnmanagedType.I1)]
public bool isGuest;
}
Это все кажется для работы. Обратный вызов в C# запускается, а члены структуры имеют ожидаемые значения.
Но после возврата к собственному коду инициируется исключение кучи (0xc0000374).
Очевидно, я хотел бы избежать этого.
Если я изменяю сигнатуру обратного вызова C#, чтобы использовать IntPtr вместо параметра ref ref_request, а затем маршал его вручную, используя следующий код, который он работает.
var request = Marshal.PtrToStructure<application_request>(requestptr);
Но я хотел бы, чтобы подпись была максимально точной и не должна была использовать Маршалер.
Есть ли у меня возможность изменить подпись делегата callback, так что .net может автоматически преобразовывать структуру?
Ошибка возникает из-за несоответствия размера возвращаемого параметра. IntPtr имеет четыре байта, поэтому вы должны объявить в C# возвращаемый параметр как четыре байта. Расположение указателя также должно быть в статическом пространстве памяти для работы кода c и C#. IntPtr будет работать, поскольку он находится в неуправляемом статическом пространстве памяти. Управляется объект C#, который даст ошибку, если он помещен в неуправляемое пространство. – jdweng
Проблема заключается не в возвращаемом значении, а в параметре ввода указателя на структуру. Есть ли способ отметить это, поэтому он помещается в неуправляемое пространство? – RasmusW
@jdweng Возвращаемое значение выглядит как перечисление нет? –