WPF调用自己写的DLL,卡死,程序正常运行了

时间:2021-04-03 14:15:00
描述下,楼主做的WPF界面,调用了一个自己写的DLL。代码本身是没有问题,但是在调试的时候,程序运行正常,但UI界面却处于无法选中的状态,我觉得是没有退出调用DLL的这个线程。。。有可能是线程托管么?
直接上图。。。PS:另外一个自己写的DLL则可以成功调用并返回。而这个卡死的DLL调用内部设计到了一些网卡操作,用的winpcap开发包。。。应该没有什么问题
///////////////////////以下两张图显示了程序是正常运行的
WPF调用自己写的DLL,卡死,程序正常运行了
WPF调用自己写的DLL,卡死,程序正常运行了
///////////////////////
上图里最右边的图标即是楼主的窗口程序,处于无法响应,点不开的状态
我的问题就是,为什么会卡死,如何解决?
//////////////////////程序切片

namespace WpfApplication2
{
class MyClass1 : INotifyPropertyChanged
{
。。。
}
 public class MyTransDll
    {
        [DllImport("MyTransDll.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]//函数调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配
        public static extern int MyTrans([MarshalAs(UnmanagedType.LPStr)]StringBuilder exportpath, [MarshalAs(UnmanagedType.LPStr)]StringBuilder importpath);
    }
public partial class Main : Window
{
。。。
 private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            //int isornotsuccess = 1;
        
            myout.Result = " Transforming,please wait....";//按下按钮之后马上显示正在传输
            System.Windows.Data.Binding bind3 = new System.Windows.Data.Binding();
            bind3.Source = myout;
            bind3.Path = new PropertyPath("Result");
            this.MyLabel.SetBinding(System.Windows.Controls.Label.ContentProperty, bind3);
            //int isornotsuccess = 1;
            int isornotsuccess = MyTransDll.MyTrans(exportpath, importpath);
           
            if (isornotsuccess == 1)
            {
                myout.Result = exportpath.ToString();
                //myout.Result = "transforming success,we can do some analyse";
                System.Windows.Data.Binding bind2 = new System.Windows.Data.Binding();
                bind2.Source = myout;
                bind2.Path = new PropertyPath("Result");
                this.MyLabel.SetBinding(System.Windows.Controls.Label.ContentProperty, bind2);                          
 }
}
}
}



//////////////////////////一下为DLL代码


int MyTrans(char* exportpath,char* importpath)
{
//省略
char A[]="regenerate_original_picture.txt";
char PA[1024];//What stored in PA is not a value but a pine
sprintf(PA,"%s\\%s",exportpath,A);//连接字符串
char *Str1="\\" ;
char *Str2="/" ;
rep(PA,Str1,Str2);
char B[]="result.txt";
char PB[1024];
sprintf (PB,"%s\\%s",importpath,B);
rep(PB,Str1,Str2);
FILE *fpopen = fopen(PA, "rb");
    FILE *fpwr = fopen(PB, "wb");
//省略
while((res = pcap_next_ex(adhandle, &header,&pkt_data)) >= 0)
{
if (res == 0)
continue;
else 

if (pkt_data[6] == 170)
{
if(pkt_data[15] == 2)
{

  for(i=0;i<256;++i)
   {
  wbuff[i]=pkt_data[i+19];//和上面类似的操作

    }
   /* cnt=cnt+1;printf("some part of received data are:");
for (int ik= 0; ik < 13; ik++)
{
printf("%d",wbuff[32+ik]);
}
*/
    fwrite(wbuff,256,1,fpwr);//以流的形式读buff
    printf("get %d\n",cnt);//收到结果数据包
                     if(cnt==1024)
break;
}
}
}


pcap_close(adhandle);
//getch();
//system("pause");
return 1; }





///////////////////////////////////

12 个解决方案

#1


vs以管理员权限运行

#2


用多线程

private void Button_Click_2(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem((object o)=>
{
  //你的代码,注意控件用Dispatcher.Invoke
});
}

#3


把调用dll的操作 放到后台操作试试

#4


当前线程一直被你那个dll阻塞吧

#5


引用 4 楼 starfd 的回复:
当前线程一直被你那个dll阻塞吧


对,应该是。。。只是不知道怎么搞多线程。。。给个sample最好

引用 2 楼 sunny906 的回复:
用多线程

private void Button_Click_2(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem((object o)=>
{
  //你的代码,注意控件用Dispatcher.Invoke
});
}


多谢2楼,能再多说一些么,楼主新手啊。。。

#6


引用 1 楼 porenasckx 的回复:
vs以管理员权限运行


这有什么关系?

#7


引用 3 楼 duanzi_peng 的回复:
把调用dll的操作 放到后台操作试试


不太懂,WPF下,后台操作是指什么?

#8


查下Task相关,或者委托异步
因为看你都是要根据执行结果进行下一步处理的

#9



 private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            //int isornotsuccess = 1;
           ThreadPool.QueueUserWorkItem((object o)=>
{
            myout.Result = " Transforming,please wait....";//按下按钮之后马上显示正在传输
            System.Windows.Data.Binding bind3 = new System.Windows.Data.Binding();
            bind3.Source = myout;
            bind3.Path = new PropertyPath("Result");

            this.MyLabel.Dispatcher.Invoke(new Action(()=>
            this.MyLabel.SetBinding(System.Windows.Controls.Label.ContentProperty, bind3)));
            //int isornotsuccess = 1;
            int isornotsuccess = MyTransDll.MyTrans(exportpath, importpath);
            
            if (isornotsuccess == 1)
            {
                myout.Result = exportpath.ToString();
                //myout.Result = "transforming success,we can do some analyse";
                System.Windows.Data.Binding bind2 = new System.Windows.Data.Binding();
                bind2.Source = myout;
                bind2.Path = new PropertyPath("Result");

                this.MyLabel.Dispatcher.Invoke(new Action(()=>
                this.MyLabel.SetBinding(System.Windows.Controls.Label.ContentProperty, bind2)));                          
             }
});
}

#10


引用 6 楼 wangzhihongji 的回复:
Quote: 引用 1 楼 porenasckx 的回复:

vs以管理员权限运行


这有什么关系?


具体情况我也不了解,主要是有些操作可能需要管理员权限,比如对注册表的操作,不知道调用网卡是否需要管理员权限,只是提个建议...

#11


DLL中有函数,阻塞了你的主进程 。

#12


非常感谢大家,这个问题暂时没有解决,这两天看了下怎么用TASK和ThreadPool,虽然TASK比较好用。


引用 11 楼 unearth 的回复:
DLL中有函数,阻塞了你的主进程 。


如11楼所说,DLL中柱塞了线程,还在debug中。。。

先把贴子结了。人人有份

#1


vs以管理员权限运行

#2


用多线程

private void Button_Click_2(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem((object o)=>
{
  //你的代码,注意控件用Dispatcher.Invoke
});
}

#3


把调用dll的操作 放到后台操作试试

#4


当前线程一直被你那个dll阻塞吧

#5


引用 4 楼 starfd 的回复:
当前线程一直被你那个dll阻塞吧


对,应该是。。。只是不知道怎么搞多线程。。。给个sample最好

引用 2 楼 sunny906 的回复:
用多线程

private void Button_Click_2(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem((object o)=>
{
  //你的代码,注意控件用Dispatcher.Invoke
});
}


多谢2楼,能再多说一些么,楼主新手啊。。。

#6


引用 1 楼 porenasckx 的回复:
vs以管理员权限运行


这有什么关系?

#7


引用 3 楼 duanzi_peng 的回复:
把调用dll的操作 放到后台操作试试


不太懂,WPF下,后台操作是指什么?

#8


查下Task相关,或者委托异步
因为看你都是要根据执行结果进行下一步处理的

#9



 private void Button_Click_2(object sender, RoutedEventArgs e)
        {
            //int isornotsuccess = 1;
           ThreadPool.QueueUserWorkItem((object o)=>
{
            myout.Result = " Transforming,please wait....";//按下按钮之后马上显示正在传输
            System.Windows.Data.Binding bind3 = new System.Windows.Data.Binding();
            bind3.Source = myout;
            bind3.Path = new PropertyPath("Result");

            this.MyLabel.Dispatcher.Invoke(new Action(()=>
            this.MyLabel.SetBinding(System.Windows.Controls.Label.ContentProperty, bind3)));
            //int isornotsuccess = 1;
            int isornotsuccess = MyTransDll.MyTrans(exportpath, importpath);
            
            if (isornotsuccess == 1)
            {
                myout.Result = exportpath.ToString();
                //myout.Result = "transforming success,we can do some analyse";
                System.Windows.Data.Binding bind2 = new System.Windows.Data.Binding();
                bind2.Source = myout;
                bind2.Path = new PropertyPath("Result");

                this.MyLabel.Dispatcher.Invoke(new Action(()=>
                this.MyLabel.SetBinding(System.Windows.Controls.Label.ContentProperty, bind2)));                          
             }
});
}

#10


引用 6 楼 wangzhihongji 的回复:
Quote: 引用 1 楼 porenasckx 的回复:

vs以管理员权限运行


这有什么关系?


具体情况我也不了解,主要是有些操作可能需要管理员权限,比如对注册表的操作,不知道调用网卡是否需要管理员权限,只是提个建议...

#11


DLL中有函数,阻塞了你的主进程 。

#12


非常感谢大家,这个问题暂时没有解决,这两天看了下怎么用TASK和ThreadPool,虽然TASK比较好用。


引用 11 楼 unearth 的回复:
DLL中有函数,阻塞了你的主进程 。


如11楼所说,DLL中柱塞了线程,还在debug中。。。

先把贴子结了。人人有份