关于网友提出的“WPF调用自己写的DLL,卡死,程序正常运行了”问题疑问,本网通过在网上对“WPF调用自己写的DLL,卡死,程序正常运行了”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题:WPF调用自己写的DLL,卡死,程序正常运行了
描述: 描述下,楼主做的WPF界面,调用了一个自己写的DLL。代码本身是没有问题,但是在调试的时候,程序运行正常,但UI界面却处于无法选中的状态,我觉得是没有退出调用DLL的这个线程。。。有可能是线程托管么?
直接上图。。。PS:另外一个自己写的DLL则可以成功调用并返回。而这个卡死的DLL调用内部设计到了一些网卡操作,用的winpcap开发包。。。应该没有什么问题
///////////////////////以下两张图显示了程序是正常运行的


///////////////////////
上图里最右边的图标即是楼主的窗口程序,处于无法响应,点不开的状态
我的问题就是,为什么会卡死,如何解决?
//////////////////////程序切片
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; }
///////////////////////////////////
解决方案1: DLL中有函数,阻塞了你的主进程 。
解决方案2:
具体情况我也不了解,主要是有些操作可能需要管理员权限,比如对注册表的操作,不知道调用网卡是否需要管理员权限,只是提个建议...
解决方案3:
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)));
}
});
}
解决方案4: 查下Task相关,或者委托异步
因为看你都是要根据执行结果进行下一步处理的
解决方案5: 当前线程一直被你那个dll阻塞吧
解决方案6: 把调用dll的操作 放到后台操作试试
解决方案7: 用多线程
private void Button_Click_2(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem((object o)=>
{
//你的代码,注意控件用Dispatcher.Invoke
});
}
以上介绍了“WPF调用自己写的DLL,卡死,程序正常运行了”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/1172526.html