需要帮助解决 AccessViolationException with C#/C 互操作
本文关键字:互操作 with AccessViolationException 帮助 解决 | 更新日期: 2023-09-27 18:33:43
我需要一些帮助来修复持久的访问违规异常。
给定这样的 c 签名
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 。
- 可能更多绝望的事情不应该产生影响
任何帮助非常感谢!
如果有人可以提供帮助,我可以分享该项目的压缩文件 - 它将像我试图与之互操作的 Mosquitto 一样获得 BSD 许可。
我最终创建了一个C++/CLI项目来将C项目包装到.NET。
我发现使用 C++ 管理非托管代码要容易得多,并且当我的类变得可访问 .NET 时,我最终获得了与 C# 的良好互操作。
我会推荐这条路径,并且会自己做 - 下次我需要将 C# 与 C 库集成时。