我正在开发一个 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/