从C ++代码向C#代码发送calllback时,访问冲突读取位置0x00000004

时间:2016-06-29 12:07:02

标签: 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";
            }
        }
}
  

下面是C ++代码,它将事件消息发送到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 calllbacks后,我的应用程序提供了访问冲突异常,之后无效。我怀疑我将函数指针从C#传递给C ++但无法解决它的方式。

1 个答案:

答案 0 :(得分:3)

你的问题是,callback_delegate被垃圾收集。

MSDN

  

您必须手动防止垃圾收集器从托管代码收集委托。垃圾收集器不跟踪对非托管代码的引用。

试试这个

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";
        }
    }
}