Нужна помощь в разрешении AccessViolationException с C#/C взаимодействия

Мне нужна помощь в исправлении постоянного AccessViolationException.

С учетом такой подписи

struct message {
    char *topic;
    void *payload;
    int payloadlen;
};

__declspec(dllexport) void callback_set(struct data *dat, void (*on_publish)(struct data *, void *, const struct message *));

У меня есть этот C#

    public struct message 
    {
        public string topic;
        public IntPtr payload;
        public int payloadlen;
    };


    /* INTEROP ACCESS */
    public delegate void on_publish(IntPtr dat, IntPtr usrData, IntPtr messageData);

    [DllImport(dllPath, CallingConvention = CallingConvention.Cdecl)]
    public extern static void callback_set(IntPtr dat, IntPtr callback);

    /* IMPLEMENTATION OF OUR on_publish*/
    public static void MessageHandler(IntPtr dat, IntPtr usrData, IntPtr messageData)
    {
        var instance = (message)Marshal.PtrToStructure(messageData, typeof(message));
        string test = instance.topic; // <-- this is successfully received
        Console.WriteLine("message rec " + test);
    } //<-- as soon as I exit, the dll blows up with access violation


    /* REGISTERING MESSAGEHANDLER AS ON_PUBLISH */
    public static void RegisterMessageHandler(IntPtr dat) //<-- I promise, the pointer I send here is valid and not modified
    {
        messageHandler = new on_publish(MessageHandler);
        messageHandlerPtr = Marshal.GetFunctionPointerForDelegate(messageHandler);
        callback_set(dat, messageHandlerPtr); //<-- if I do not call this, everything works, no ADE
        Console.WriteLine("message handler registered");
    }
    //just tried to move to scope in order to retain their managed memory loc
    private static IntPtr messageHandlerPtr;  
    private static on_publish messageHandler;

При запуске и убедитесь, что сообщение должно быть получено - я получаю правильную строку для topic но как только MessageHandler возвращается, я получаю страшное исключение.

Вещи, которые я пробовал:

  • Изменить CallingConvention
  • Используйте on_publish вместо IntPtr в определении управляемого callback_set
  • Вероятно, больше вещей в отчаянии, которые не должны оказывать влияние

Любая помощь высоко ценится!

Я могу поделиться zip проекта, если кто-нибудь может помочь - это будет лицензия BSD, как у Mosquitto, с которой я пытаюсь взаимодействовать.

1 ответ

Решение

Я закончил тем, что создал проект C++/CLI для переноса проекта C в.NET.

Мне стало намного проще управлять неуправляемым кодом с помощью C++, и я получил хорошее взаимодействие с C#, поскольку мой класс стал доступным для.NET.

Я бы порекомендовал этот путь, и я сделаю это сам - в следующий раз мне нужно интегрировать C# с C lib.

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