Маршал обратного вызова в структуре от C ++ до C # - PullRequest
0 голосов
/ 26 февраля 2019

Мне нужно вернуть необходимую информацию об объекте в виде структуры с обратными вызовами и другими данными.

Вот как это выглядит на стороне C #:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ChartAddDataCallback(IntPtr data, int size);

[StructLayout(LayoutKind.Sequential)]
public struct ChartAccessors
{
    public IntPtr HWnd;
    public ChartAddDataCallback addDataCallback;
}

[DllImport("CppPart.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "GetAccessors")]
public static extern ChartAccessors GetAccessors();

«Зеркальная» версия C ++ выглядит так:

typedef void(__cdecl *AddDataCallback) (int * data, int size);

struct ChartAccessors
{
    HWND m_chartHWnd;
    AddDataCallback m_addDataCallback;
};

extern "C" __declspec(dllexport) ChartAccessors GetAccessors();

Использование:

static void Main(string[] args)
{
    ChartAccessors accessors = GetAccessors();
}

Однако, когда я запускаю программу, я получаю исключение «Подпись типа метода не совместима с PInvoke.»
Это работает, если я использую любой другой тип возвращаемого значения (например, int или float) вместо struct.

1 Ответ

0 голосов
/ 16 мая 2019

Marshal.PtrToStructure фактически решала эту проблему, как указывал Павел .

void RegisterCallbacks(IntPtr callbackPtr)
{
    ChartAccessors accessors = (ChartAccessors)Marshal.PtrToStructure(callbackPtr, typeof(ChartAccessors));
    // do stuff with the struct
}
...