关于C#调用DLL和C线程回调C#代码问题,大家探讨下。。。。

smallmice 2011-12-21 03:03:45
我使用VC创建了一个DLL文件,这个DLL文件唯一特殊地方是它创建一个线程,该线程可以回调C#代码?
问题出现在回调几次后C#程序出错挂掉。

VC 程序如下:Test.DLL

typedef 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 时发生访问冲突。
...全文
239 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
smallmice 2011-12-22
  • 打赏
  • 举报
回复
DLL文件是使用VC编译的。
仙剑 2011-12-22
  • 打赏
  • 举报
回复
我也遇到类似的问题,帮忙顶!
smallmice 2011-12-22
  • 打赏
  • 举报
回复
不是因为资源没有释放原因,在DLL中C语音创建一个非托管线程,C#程序无法管理那个非托管线程。
如果是因为字节不对其造成的话,那就第一次回调时候就该失败了,可是在成功回调几次C#线程挂掉了,C创建的线程还一直运行着,这时候C#主界面就未响应了。有人说delegrate创建的函数指针和C语音中的函数指针是不一样的,由于对两个语音汇编原理不太清楚,我也不太确定。有时间大家可以尝试下。
我现在改变思路了,用C#中线程循环调用DLL中代码,这样托管线程安全些。
Saleayas 2011-12-21
  • 打赏
  • 举报
回复
尝试修改 C++ 的 函数。
添加 WINAPI 。
或者修改 C# 中的委托。
设置 CallingConvention = Cdecl。
qq598235031 2011-12-21
  • 打赏
  • 举报
回复
没搞明白,是你C++程序使用.net编译的DLL,还是.net 使用C++编译的DLL?
mjp1234airen4385 2011-12-21
  • 打赏
  • 举报
回复
以前写过一个程序,调用别人C++写的dll,里面包含了n个线程。
就是这个样子,调用几次,就挂掉。
最后也没找到什么好办法,不过项目最后不做了。

你试试,GC.KeepAlive(object),这个事件,当时是没有找到这个方法,也没有测试。

你试试看行不行。


csdn_aspnet 2011-12-21
  • 打赏
  • 举报
回复
是不是有些资源还没来得急释放掉啊 http://www.web521.com/asp.net/513368/T610357.shtml

110,568

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧