求教如何解决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#