当前位置:编程学习 > C#/ASP.NET >>

求教如何解决C#调用C++ DLL出现“尝试读取或写入受保护的内存。这通常指示其他内存已损坏”错误

我正在编写设备处理程序,使用C++写的DLL,其中一个部分需要用到回调函数。
现在遇到的问题是使用 InitDevice() 函数后,回调函数能够正常运行获取返回数据,但是随后调用Close()函数,就会导致系统报出“尝试读取或写入受保护的内存。这通常指示其他内存已损坏”错误。
使用了N种方式也没有解决这个问题,有哪位高手能够帮帮忙啊!

C++函数原形如下:
extern "C" __declspec(dllexport) HANDLE  __stdcall Login(const char* chDevIP, unsigned int nDevPort, const char* chUserName, const char* chPasswd);
extern "C" __declspec(dllexport) void    __stdcall SetCallBack(
            const char* chDevType,                  //设备类型
            RealDataCallBack fnCallBack,        //回调函数
            const char* szLocalIp,                      //本机ip
            const char* szDevIp,                        //设备ip
            WORD iChannel,                              //通道编号                          
            UINT Transmode,                            //传输方式
            HANDLE hUserHandle);                  //登陆句柄

extern "C" __declspec(dllexport) bool    __stdcall Logout(HANDLE hUserHandle); 

我的C#定义:
//登录设备
[DllImport("device.dll", EntryPoint = "Login")]
public unsafe static extern IntPtr Login(string strDevIP, uint iDevPort, string strUserName, string strPasswd);

//设置回调
[DllImport("device.dll", EntryPoint = "SetCallBack")]
public unsafe static extern void SetCallBack(
                string strDevType,
                [MarshalAs(UnmanagedType.FunctionPtr)]RealDataCallBack fnCallBack,
                string strLocalIp,
                string strDevIp,
                uint iChannel,
                uint iTransmode,
                IntPtr lHandle);

//退出登录,其中调用了SetCallBack函数将回调函数设置为NULL
[DllImport("device.dll", EntryPoint = "Logout")]
public unsafe static extern void Logout(IntPtr lHandle);

/// 定义回调接口
public unsafe delegate bool RealDataCallBack(IntPtr objPr, int iLen);

private RealDataCallBack _fnCallBack;

_fnCallBack = new RealDataCallBack(this.BroadcastMessage);

        public void InitDevice()
        {
            //登录设备
            _lHandle = Login(_objDevInfo.DeviceIP, _objDevInfo.DevicePort, _objDevInfo.User, _objDevInfo.Password);
            if (_lHandle.ToInt32() > 0 )
            {
                        SetCallBack(
                                _objDevInfo.DeviceType,
                                _fnCallBack,
                                _objLocalAddress.ToString(),
                                _objDevInfo.DeviceIP,
                                _objDevInfo.Channel,
                                _objDevInfo.TransMode,
                                _lHandle
                                );
            }
            else
            {
                throw (new ApplicationException("登录设备失败."));
            }
        }

        private bool BroadcastMessage(IntPtr objPr, int iLen)
        {
            try
            {
                byte[] byteData = new byte[iLen];
                Marshal.Copy(objPr, byteData, 0, iLen);
                //以下做数据处理工作

                return true;
            }
            catch (Exception ex)
            {
                //失败处理
            }
        }

        //关闭设备
        public void Close()
        {
            try
            {
                if ( _lHandle.ToInt32() > 0 )
                {
                    //退出设备登录
                    Logout(_lHandle);
                }
            }
            catch (Exception ex)
            {
                throw (ex);
            }
            finally
            {
                _lHandle = (IntPtr)( - 1);
            }
        }  --------------------编程问答-------------------- 参数类型改了
把ref去掉
或者允许
不安全代码 --------------------编程问答-------------------- [unsafe] --------------------编程问答-------------------- 如果按照你这么所说的话
我想应该是c#分配的deleage地址。在c里面只能访问 不能操作吧
没有遇到你这样的问题。呵呵。
也不知道你c里面怎么写的 --------------------编程问答-------------------- 我一直认为问题是出现在回调函数使用上,但是一直找不到原因,所以需要高手们帮忙! --------------------编程问答-------------------- 而且只要出现内存错误情况后,再次调用 SetCallBack 函数,就会直接出现“尝试读取或写入受保护的内存。这通常指示其他内存已损坏”错误。
真是郁闷啊!
请高手们快快出招!!!
--------------------编程问答-------------------- 我顶
补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,