0

我需要一些帮助来修复持久的 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返回,我就会得到可怕的异常。

我尝试过的事情:

  • 改变呼叫约定
  • 在托管的 callback_set 定义中使用 on_publish 而不是 IntPtr
  • 可能还有更多不应该产生影响的绝望的事情

非常感谢任何帮助!

如果有人可以提供帮助,我可以分享该项目的 zip - 它将获得 BSD 许可,就像我试图与之互操作的 Mosquitto 一样。

4

1 回答 1

0

我最终创建了一个C++/CLI项目来将 C 项目包装到 .NET。

我发现使用 C++ 管理非托管代码要容易得多,并且随着我的类变得可访问 .NET,我最终获得了与 C# 的良好互操作。

我会推荐这条路径,并且会自己做——下次我需要将 C# 与 C lib 集成时。

于 2014-12-12T09:41:29.997 回答