Нужна помощь в разрешении 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.