c# - 从 C++ 代码向 C# 代码发送回调时访问冲突读取位置 0x00000004

标签 c# c++ visual-studio windows-ce

我正在开发一个 Windows 8 手机应用程序,我需要在其中将回调事件消息从 C++ 代码发送到 C# 中的 UI 代码。下面是 C# 代码,我在其中创建回调函数并将它的指针发送到 C++ 代码。 C++ 代码可以使用此函数指针向 UI 发送异步事件消息。

C#代码

public partial class MainPage
{
        public MainPage()
        {
            InitializeComponent();
        }
        public delegate void CallBack([In][MarshalAs(UnmanagedType.LPStr)] string strParam);
        [DllImport("Test.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern void PerformActionWithCallBack(int x);

        void DemonstrateCallBack()
        {
            int x;
            CallBack callback_delegate = new CallBack(CallBackFunction);
            // Converting callback_delegate into a function pointer that can be
            // used in unmanaged code.
            IntPtr intptr_delegate = Marshal.GetFunctionPointerForDelegate(callback_delegate);

            //Getting the pointer into integer value and sending it to C++

            x = (int)intptr_delegate;

            testApp.PerformActionWithCallBack(x);
        }

        //CallBack function in which event messages will be received
        void CallBackFunction([In][MarshalAs(UnmanagedType.LPStr)] string strParam)
        {
            if (Dispatcher.CheckAccess() == false)
            {
                //Updating the text block with the received message
                Dispatcher.BeginInvoke(() => MyTextBlock.Text = strParam);
            }
            else
            {
                MyTextBlock.Text = "Update directly";
            }
        }
}

Below is the C++ code which will send event messages to C#

//Callback function prototype
typedef void(__stdcall *PCallBack)(LPSTR s);
LPSTR cbMsg = NULL;

//Global instance callback function
PCallBack gUICallback;

void TestApp::PerformActionWithCallBack(int x)
{
    //Assigning the received calllback function pointer from C# to global function pointer
    gUICallback = (PCallBack)x;
}

//This function will send event messages to C#
void SendCallbackMsg()
{
    while(1)
    {
         cbMsg = "Hello";
         Sleep(100);
         gUICallback(cbMsg);
         cbMsg = "Hi";
         Sleep(100);
         gUICallback(cbMsg);
    }
 }

使用此代码,我能够在 C# 中成功获取事件消息,但在发送 650-700 个回调后,我的应用程序给出了访问冲突异常,此后没有任何效果。我怀疑我将函数指针从 C# 传递到 C++ 但无法解析它的方式。

最佳答案

您的问题是,callback_delegate 被垃圾回收。

MSDN

You must manually keep the delegate from being collected by the garbage collector from managed code. The garbage collector does not track reference to unmanaged code.

试试这个

public partial class MainPage
{
    private CallBack _callBackDelegate = null;
    public MainPage()
    {
        InitializeComponent();
    }
    public delegate void CallBack([In][MarshalAs(UnmanagedType.LPStr)] string strParam);
    [DllImport("Test.dll", CallingConvention = CallingConvention.StdCall)]
    public static extern void PerformActionWithCallBack(int x);

    void DemonstrateCallBack()
    {
        _callBackDelegate = new CallBack(CallBackFunction);
        int x;

        // Converting _callBackDelegate  into a function pointer that can be
        // used in unmanaged code.
        IntPtr intptr_delegate = Marshal.GetFunctionPointerForDelegate(_callBackDelegate );

        //Getting the pointer into integer value and sending it to C++

        x = (int)intptr_delegate;

        testApp.PerformActionWithCallBack(x);
    }

    //CallBack function in which event messages will be received
    void CallBackFunction([In][MarshalAs(UnmanagedType.LPStr)] string strParam)
    {
        if (Dispatcher.CheckAccess() == false)
        {
            //Updating the text block with the received message
            Dispatcher.BeginInvoke(() => MyTextBlock.Text = strParam);
        }
        else
        {
            MyTextBlock.Text = "Update directly";
        }
    }
}

关于c# - 从 C++ 代码向 C# 代码发送回调时访问冲突读取位置 0x00000004,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38099052/

相关文章:

c++ - 为温度程序选择合适的值

c++ - 我如何使用位操作对单个整数中的两个数字进行编码和解码?

visual-studio - 从 DataSet Visualizer 复制粘贴行数据和列标题?

c++ - vs c++ dll - 标量删除析构函数

c# - 旧版本的 .Net 没有安装最新的 Mono?

c# - Foreach/For 循环替代 lambda 函数?

c# - LINQ - VB.Net 中的动态 OrderBy

c# - 重复子串 N 次

c# - 纯粹在 xaml 中连接文字和静态资源字符串

c++ - 将 Child 对象数组传递给接受 Parent* 的函数