У меня есть неуправляемая dll, которая экспортирует следующую функцию:
SomeData* test();
Предположим SomeData как:
typedef struct _Data Data;
struct _Data{
int a;
int b;
}
Теперь я хочу вызвать эту функцию из кода C #. Я начинаю определять C # Struture, необходимый для пользовательского маршалинга, следующим образом:
[StructLayout(LayoutKind.Sequential)]
public class SomeData
{
public Int32 a;
public Int32 b;
}
А теперь я объявляю управляемую функцию:
[DllImport("DynamicLibrary.dll", CharSet=CharSet.Auto)]
[return: MarshalAs(UnmanagedType.LPStruct)]
public static extern SomeData test();
А в основной функции у меня есть:
IntPtr ptr = test();
Делая это, я получаю исключение MarchalDirectiveException: «Невозможно выполнить маршализацию« возвращаемого значения »: недопустимая комбинация управляемого / неуправляемого типа (Int / UInt должен быть связан с SysInt или SysUInt).
Я не выделил память для SomeData в C #, так как я ожидаю, что эта память выделена в функции C, и я бы использовал Marshal.Copy, чтобы передать ее в управляемую память.
Есть идеи? Спасибо
------------------------ Отредактировано ПОСЛЕ ОТВЕТА JaredPar ------------------- -
На самом деле, я допустил ошибку при копировании кода на мой вопрос. Реальная управляемая подпись, которую я использовал, была:
[DllImport ("DynamicLibrary.dll", CharSet = CharSet.Auto)]
[возвращение: MarshalAs (UnmanagedType.LPStruct)]
public static extern IntPtr test ();
Ответ JaredPar по-прежнему актуален. Чтобы получить правильное поведение, у меня есть 2 варианта:
1) Используйте 'public static extern IntPtr test ();' (без атрибута MarshalAs) подпись, а затем доступ к возвращенному указателю, как предложил JaredPar.
2) Использовать 'public static extern SomeData test ();' (с атрибутом MarshalAs), а затем просто используйте SomeData sd = test ();