我使用VC创建了一个DLL文件,这个DLL文件唯一特殊地方是它创建一个线程,该线程可以回调C#代码?
问题出现在回调几次后C#程序出错挂掉。VC 程序如下:Test.DLLtypedef int(*InputFunction)();
typedef int(*OutputFunction)();
//全局变量
InputFunction SpexInputFunction=NULL;
OutputFunction SpexOutputFunction=NULL;
int IsStop=0;
HANDLE spexthread=NULL; 
DWORD spexthreadID;static DWORD WINAPI ThreadProc(LPVOID lpParam)
{
while(IsStop ==1)
{
Sleep(5000);
SpexInputFunction();
}
SpexOutputFunction();
return 0;
}
//初始化函数指针
int Start(SpeexInputFunction inputfun,SpeexOutputFunction outputfun)
{    SpexInputFunction=inputfun;
    SpexOutputFunction=outputfun;
    IsStop=1;
    spexthread=CreateThread(NULL,NULL,ThreadProc,NULL,0,&spexthreadID);
}
void SpeexNativeStop()
{
IsStop=0;
WaitForSingleObject(spexthread,INFINITE);
CloseHandle(spexthread);
}C#调用 Start C语言创建一个线程,该线程回调C#中的函数。C#代码如下:
    public delegate int DelegateInput();
    public delegate int DelegateOutput();
    public partial class Form1 : Form
    {        [DllImport("Test.DLL")]
        internal static extern int Start(DelegateSpeexInput inputfucntion,DelegateSpeexOutput outputfunction);
        [DllImport("Test.DLL")]
        internal static extern int Stop();       public static  int Input()
        {
          
            //MessageBox.Show("InputFunction");
            return 0;
        }
       public static   int OutPut()
        {
           // MessageBox.Show("OutPutFunction");
            return 0;
        }        private DelegateInput spexinput = new DelegateInput(Input);
        private DelegateOutput spexoutput = new DelegateOutput(OutPut);        public Form1()
        {
            InitializeComponent();
        }        private void button1_Click(object sender, EventArgs e)
        {
            int result=Start(spexinput, spexoutput);
            //MessageBox.Show(result.ToString());
        }        private void button2_Click(object sender, EventArgs e)
        {
            Stop();
        }
    }主要代码我已经写出来了,大家一起探讨下。现象是C创建的线程头几次回调是没有问题的,回调次数多了C#主程序就挂掉了。错误提示:中的 0x0365bc00 处未处理的异常: 0xC0000005: 写入位置 0x03770000 时发生访问冲突。

解决方案 »

  1.   

    是不是有些资源还没来得急释放掉啊  http://www.web521.com/asp.net/513368/T610357.shtml
      

  2.   

    以前写过一个程序,调用别人C++写的dll,里面包含了n个线程。
    就是这个样子,调用几次,就挂掉。
    最后也没找到什么好办法,不过项目最后不做了。你试试,GC.KeepAlive(object),这个事件,当时是没有找到这个方法,也没有测试。你试试看行不行。
      

  3.   

    没搞明白,是你C++程序使用.net编译的DLL,还是.net 使用C++编译的DLL?
      

  4.   

    尝试修改 C++ 的 函数。
    添加 WINAPI 。
    或者修改 C# 中的委托。
    设置 CallingConvention = Cdecl。
      

  5.   

    不是因为资源没有释放原因,在DLL中C语音创建一个非托管线程,C#程序无法管理那个非托管线程。
    如果是因为字节不对其造成的话,那就第一次回调时候就该失败了,可是在成功回调几次C#线程挂掉了,C创建的线程还一直运行着,这时候C#主界面就未响应了。有人说delegrate创建的函数指针和C语音中的函数指针是不一样的,由于对两个语音汇编原理不太清楚,我也不太确定。有时间大家可以尝试下。
    我现在改变思路了,用C#中线程循环调用DLL中代码,这样托管线程安全些。