首页 新闻 会员 周边

WPF调用C++DLL,callback函数多次调用被回收的问题

0
悬赏园豆:20 [已解决问题] 解决于 2014-08-12 16:02
    public delegate void UpdateFinishedCallBack(bool bSucess, string errorMsg);
    public delegate void UpdateProgressCallBack(int iTotal, int iCur, string fileName);
        [DllImport("xxx.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern bool StartUpdate(UpdateFinishedCallBack ufcb, UpdateProgressCallBack upcb);

        public  void Update_Progress_cb(int iTotal, int iCur, string fileName)
        {
            del_do_changetxt delchangetxt = ChangeTextMethod;
            Dispatcher.BeginInvoke(delchangetxt, new object[] { iCur.ToString() });
        }
        private  void ChangeTextMethod(string text)
        {
            lbltext.Content = text;
        }
private delegate void del_do_changetxt(string str);

主要代码如下,我在使用

StartUpdate(Update_Finished_cb, Update_Progress_cb);

多次回调了Update_Progress_cb方法,提示

经测试 Update_Progress_cb 该方法加上static 代码完美执行,不能那么做因为我需要使用

Dispatcher.BeginInvoke 函数,求指教
shrimp liao的主页 shrimp liao | 初学一级 | 园豆:135
提问于:2014-08-12 14:50
< >
分享
最佳答案
1

UpdateFinishedCallBack ufcb, UpdateProgressCallBack upcb 这两个变量要在回调完成前保持活动状态。

收获园豆:15
Launcher | 高人七级 |园豆:45045 | 2014-08-12 15:15

能说的具体点吗?我也有查资料,说延长垃圾回收的时间,或者修改成全局变量

您说的,保持活动该怎么做呢?

shrimp liao | 园豆:135 (初学一级) | 2014-08-12 15:17

@shrimp liao: 你把调用 StartUpdate(UpdateFinishedCallBack ufcb, UpdateProgressCallBack upcb) 的代码贴出来。

Launcher | 园豆:45045 (高人七级) | 2014-08-12 15:20

@Launcher: 

public MainWindow()
{
InitializeComponent();
StartUpdate(Update_Finished_cb, Update_Progress_cb);
}

public void Update_Progress_cb(int iTotal, int iCur, string fileName)
{
del_do_changetxt_1 delchangetxt = ChangeTextMethod;
Dispatcher.BeginInvoke(delchangetxt, new object[] { iCur.ToString() });
}

shrimp liao | 园豆:135 (初学一级) | 2014-08-12 15:22

@shrimp liao: 你的 MainWindow 不是在应用程序结束时才关闭吗?

Launcher | 园豆:45045 (高人七级) | 2014-08-12 15:30

@Launcher: 这是写的测试代码,没有其他东西就是但存的做这个下载的测试,您肯定也看出来了

Update_Progress_cb 下载,返回下载进度等信息

Update_Finished_cb 下载完成,返回信息

就是因为Update_Progress_cb  会多次回调,所以才会出错,原因是因为他的生命周期不够持久,知道的版本就是加static 但是苦于无奈,我方法中使用到了其他函数,没办法使用static

shrimp liao | 园豆:135 (初学一级) | 2014-08-12 15:33

@shrimp liao: 那你不要贴测试代码,你给我贴你出错的代码。

Launcher | 园豆:45045 (高人七级) | 2014-08-12 15:35

@Launcher: 

public void Update_Progress_cb(int iTotal, int iCur, string fileName)
{
del_do_changetxt_1 delchangetxt = ChangeTextMethod;
Dispatcher.BeginInvoke(delchangetxt, new object[] { iCur.ToString() });
}

就是这个方法出的错,我不知道您具体的要什么,这是我整个代码

http://files.cnblogs.com/shrimp-liao/MainWindow.xaml.cs.zip

shrimp liao | 园豆:135 (初学一级) | 2014-08-12 15:38

@shrimp liao: Marshal.GetFunctionPointerForDelegate

Launcher | 园豆:45045 (高人七级) | 2014-08-12 15:47

@Launcher: 这个怎么使用呢...

只找到了这个

[SecurityPermissionAttribute(SecurityAction::LinkDemand, Flags = SecurityPermissionFlag::UnmanagedCode)] public: static IntPtr GetFunctionPointerForDelegate( Delegate^ d )

shrimp liao | 园豆:135 (初学一级) | 2014-08-12 15:57
Launcher | 园豆:45045 (高人七级) | 2014-08-12 16:10
其他回答(2)
0

改成这样就行了

 

private UpdateFinishedCallBack _D1;        

private UpdateProgressCallBack _D2;

        public MainWindow()        

{            

InitializeComponent();            

_D1 = new UpdateFinishedCallBack(Update_Finished_cb);            

_D2 = new UpdateProgressCallBack(Update_Progress_cb);            

StartUpdate(_D1, _D2);        

}

收获园豆:5
Firen | 园豆:5385 (大侠五级) | 2014-08-12 15:38

小弟刚才也看了http://www.cnblogs.com/blackice/archive/2013/05/22/3092478.html这篇文章,和兄弟讲的类似,刚做了测试的确可以了,可以将下为什么吗?之前的博主也没说明其原因

支持(0) 反对(0) shrimp liao | 园豆:135 (初学一级) | 2014-08-12 15:42

@shrimp liao: 因为你调用第二次 StartUpdate 时,指针地址可能被移动了,而之前回调的操作还没完成。

支持(0) 反对(0) Launcher | 园豆:45045 (高人七级) | 2014-08-12 15:49
0

真正的原因是,赋值给C++的代理是一个临时变量,被垃圾收集的关系。代理的生命周期改成成员变量就行

最后的骑士 | 园豆:202 (菜鸟二级) | 2015-08-09 17:13
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册