从C+;发送calllback时访问冲突读取位置0x00000004+;代码到C#代码 我正在开发一个Windows 8电话应用程序,其中需要将C++语言的回调事件消息发送到C语言中的UI代码。下面是我创建回调函数并将指针发送到C++代码的C代码。C++代码可以使用这个函数指针向UI发送异步事件消息。
C#代码从C+;发送calllback时访问冲突读取位置0x00000004+;代码到C#代码 我正在开发一个Windows 8电话应用程序,其中需要将C++语言的回调事件消息发送到C语言中的UI代码。下面是我创建回调函数并将指针发送到C++代码的C代码。C++代码可以使用这个函数指针向UI发送异步事件消息。,c#,c++,visual-studio,windows-ce,C#,C++,Visual Studio,Windows Ce,C#代码 public partial class MainPage { public MainPage() { InitializeComponent(); } public delegate void CallBack([In][MarshalAs(UnmanagedType.LPStr)] string strParam); [DllImport("Test.dll", CallingC
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<< /p>
有了这段代码,我可以成功地获得C#中的事件消息,但在发送650-700个Callback之后,我的应用程序会出现访问冲突异常,在这之后,一切都不起作用。我怀疑我把函数指针从C++传递到C++,但不能解析它。p> 您的问题是,回调\u委托被垃圾回收 说 必须手动防止垃圾收集器从托管代码中收集委托。垃圾收集器不跟踪对非托管代码的引用 试试这个
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";
}
}
}
当我这样做时,我必须使CallbackFunction保持静态。否则,通过“new CallBack(CallBackFunction);”初始化CallBackDelegate将返回错误,因为“字段初始值设定项不能引用非静态字段/方法”。如果我将CallbackFunction设置为静态,那么我就无法访问CallbackFunction内部的Dispatcher对象,这会导致错误,因为“非静态字段/方法需要对象引用”。看起来像是死锁。谢谢。@SanjeevKumar对不起,我不是C#程序员,所以我弄错了。您只需在构造函数中或在
void DemonstrateCallback()
方法中初始化此变量,使其保持在类中而不是静态的。我已经编辑了我的答案,修正了哈斯·克拉夫琴科案,你已经解决了我的问题。它工作得很好。非常感谢你。
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";
}
}
}