问题描述
我使用VC创建了一个DLL文件,这个DLL文件唯一特殊地方是它创建一个线程,该线程可以回调C#代码?问题出现在回调几次后C#程序出错挂掉。VC程序如下:Test.DLLtypedefint(*InputFunction)();typedefint(*OutputFunction)();//全局变量InputFunctionSpexInputFunction=NULL;OutputFunctionSpexOutputFunction=NULL;intIsStop=0;HANDLEspexthread=NULL;DWORDspexthreadID;staticDWORDWINAPIThreadProc(LPVOIDlpParam){while(IsStop==1){Sleep(5000);SpexInputFunction();}SpexOutputFunction();return0;}//初始化函数指针intStart(SpeexInputFunctioninputfun,SpeexOutputFunctionoutputfun){SpexInputFunction=inputfun;SpexOutputFunction=outputfun;IsStop=1;spexthread=CreateThread(NULL,NULL,ThreadProc,NULL,0,&spexthreadID);}voidSpeexNativeStop(){IsStop=0;WaitForSingleObject(spexthread,INFINITE);CloseHandle(spexthread);}C#调用StartC语言创建一个线程,该线程回调C#中的函数。C#代码如下:publicdelegateintDelegateInput();publicdelegateintDelegateOutput();publicpartialclassForm1:Form{[DllImport("Test.DLL")]internalstaticexternintStart(DelegateSpeexInputinputfucntion,DelegateSpeexOutputoutputfunction);[DllImport("Test.DLL")]internalstaticexternintStop();publicstaticintInput(){//MessageBox.Show("InputFunction");return0;}publicstaticintOutPut(){//MessageBox.Show("OutPutFunction");return0;}privateDelegateInputspexinput=newDelegateInput(Input);privateDelegateOutputspexoutput=newDelegateOutput(OutPut);publicForm1(){InitializeComponent();}privatevoidbutton1_Click(objectsender,EventArgse){intresult=Start(spexinput,spexoutput);//MessageBox.Show(result.ToString());}privatevoidbutton2_Click(objectsender,EventArgse){Stop();}}主要代码我已经写出来了,大家一起探讨下。现象是C创建的线程头几次回调是没有问题的,回调次数多了C#主程序就挂掉了。错误提示:中的0x0365bc00处未处理的异常:0xC0000005:写入位置0x03770000时发生访问冲突。
解决方案
解决方案二:
是不是有些资源还没来得急释放掉啊
解决方案三:
以前写过一个程序,调用别人C++写的dll,里面包含了n个线程。就是这个样子,调用几次,就挂掉。最后也没找到什么好办法,不过项目最后不做了。你试试,GC.KeepAlive(object),这个事件,当时是没有找到这个方法,也没有测试。你试试看行不行。
解决方案四:
没搞明白,是你C++程序使用.net编译的DLL,还是.net使用C++编译的DLL?
解决方案五:
尝试修改C++的函数。添加WINAPI。或者修改C#中的委托。设置CallingConvention=Cdecl。
解决方案六:
DLL文件是使用VC编译的。
解决方案七:
不是因为资源没有释放原因,在DLL中C语音创建一个非托管线程,C#程序无法管理那个非托管线程。如果是因为字节不对其造成的话,那就第一次回调时候就该失败了,可是在成功回调几次C#线程挂掉了,C创建的线程还一直运行着,这时候C#主界面就未响应了。有人说delegrate创建的函数指针和C语音中的函数指针是不一样的,由于对两个语音汇编原理不太清楚,我也不太确定。有时间大家可以尝试下。我现在改变思路了,用C#中线程循环调用DLL中代码,这样托管线程安全些。
解决方案八:
我也遇到类似的问题,帮忙顶!