public enum MPRDeviceEvent
{
    PLUGED_IN,           //设备插入
    PLUGED_OUT,          //设备设备拔出
    MPR_CODE_CAPTURED,   //点读了一个MPR码
    POWER_KEY_PRESSED,   //POWER键被按下
    UP_KEY_PRESSED,      //音量+键被按下
    DOWN_KEY_PRESSED     //音量-键被按下
}private static void ProcessMPRDeviceEvent(MPRDeviceEvent mrpevent, IntPtr p_data, int data_len)
{
    switch (mrpevent)
    {
        case MPRDeviceEvent.MPR_CODE_CAPTURED:
            {
                byte[] byteCode = new byte[data_len];
                Marshal.Copy(p_data, byteCode, 0, data_len);
                Marshal.Release(p_data);
                string strCode = string.Empty;
                for (int i = 0; i < data_len; i++)
                {
                    strCode += byteCode[i].ToString("X");
                }
                _Lable.Text = strCode;
                break;
            }
    }
}public delegate void DelegateMPRCallBack(MPRDeviceEvent mrpevent, IntPtr p_data, int data_len);public static System.Windows.Forms.Label _Lable;static DelegateMPRCallBack _CallBack;[DllImport("MPRDeviceAPI.dll")]
public static extern int MPRDevice_InitLib(DelegateMPRCallBack callBack);public static bool Start(System.Windows.Forms.Label lable)
{
    _Lable = lable;
    _CallBack = new DelegateMPRCallBack(ProcessMPRDeviceEvent);
    MPRDevice_InitLib(_CallBack);
}
以上是我用C#调用C++回调函数的部分代码,调试时,调用成功,但是调用成功后,程序就会出现未响应!!不知哪里出问题了??请高手指教!!c#回调函数

解决方案 »

  1.   

    如果data_len比较大,比如几兆,那么strCode += ...会很慢,成为瓶颈。如果是这种情况,你可以用StringBuilder:StringBuilder strCode = new StringBuilder();
    for (int i = 0; i < data_len; i++)
    {
        strCode.Append(byteCode[i].ToString("X"));
    }
    _Lable.Text = strCode.ToString();
      

  2.   


    还是一样的错误:vshost.exe 已停止工作我调试的时候 data_len = 7,并且成功执行了“_Lable.Text = strCode.ToString();”,之后程序就未响应了!!
    由于是调用C++的回调函数,参数p_data只有设置为IntPtr,然后再根据下面的代码转换,才能得到正确的Code,最后得到的Code也只有14个字节
      

  3.   

    (MPRDeviceEvent mrpevent, IntPtr p_data, int data_len); IntPtr p_data
    这个参数,定义为StringBuilder,试试看。
      

  4.   


    是一样的效果,这个回调函数里面的代码应该没有问题,每次调试的时候,都是在回调函数执行完成后就报错了:vshost.exe 已停止工作
      

  5.   

    在网上找了一个方法,但还是不行:
    http://social.msdn.microsoft.com/Forums/zh-CN/6bcf46db-2c2a-4201-9d90-5476be1c0a4f/c-dll-c-debugrelease请求帮助!!!!!
      

  6.   

    建议你直接运行生成的exe不要已调试启动
      

  7.   

    有的第三方dll用vs调试的时候会卡死直接运行生成的exe则不会
      

  8.   

    1. 把strcode改成全局变量,_Lable.Text=strcode;这句话放到自定义消息处理里去,这里替换成发送自定义消息
    2. label所在窗口的构造函数里, 在InitializeComponent();下面添加
    Control.CheckForIllegalCrossThreadCalls = false;
      

  9.   


    直接运行exe是一样的结果!!!
      

  10.   


    我把strcode改成全局变量,暂时去掉了_Lable,只是在回调函数里messagebox出来strcode,但是回调函数执行完后,程序还是自动退出了!
      

  11.   


    请问如何改成 Invoke ???
    由于我的这个回调函数是通过一个硬件设备接触到一张卡时,自动触发的!请教如何在这里使用 Invoke
      

  12.   

    C# 有自动释放内存的GC 处理机制 那么C+内存处理是不是要人工处理。光看代码 感觉没问题这个应请教下C++高手
      

  13.   


    C++ 写的这段代码我运行了,是没有问题的(我的这段代码也是按照C++写的代码改的),我在网上找的资料,很多都是说是C#自带的GC的结果,但是不知如何解决!!!
      

  14.   

    _Lable.Text  用个string 看看吧  还有用委托吧
      

  15.   


    private static void ProcessMPRDeviceEvent(MPRDeviceEvent mrpevent, IntPtr p_data, int data_len)
    {
        switch (mrpevent)
        {
            case MPRDeviceEvent.MPR_CODE_CAPTURED:
                {
                    string strCode = string.Empty;
                    _Lable.Text = strCode;
                    break;
                }
        }
    }public static bool Start(System.Windows.Forms.Label lable)
    {
        _Lable = lable;
        _CallBack = new DelegateMPRCallBack(ProcessMPRDeviceEvent);
        this.Invoke(_CallBack, new object[] { MPRDeviceEvent.MPR_CODE_CAPTURED, IntPtr.Zero, 0 });
        //MPRDevice_InitLib(_CallBack);
    }
    我如果这样调用函数,程序就没有问题!
      

  16.   

    把byte[] byteCode = new byte[data_len];  放到回调函数之外,声明成全局变量,然后在回调函数中使用这个变量,
    这样修改试试.
      

  17.   

    自己已经解决:将[System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute(System.Runtime.InteropServices.CallingConvention.Cdecl)]改掉就OK了