C#调用C++写的dll问题
有个C++写的视频服务器的SDK,需要在C#下调用,但是改来改去总是有问题,无法正确采集图像,请大虾们指点一二,谢谢!类型转换上面不知道是不是有问题,但是如果一开始调用初始化函数的时候就会报“尝试读取或写入受保护的内存...”,如果不调用初始化函数,则不报错,但是图像仍然不显示。
需要调用的C++代码
- C/C++ code
/// 设备信息typedef struct _H264_DVR_DEVICEINFO{ char sSoftWareVersion[64]; ///< 软件版本信息 char sHardWareVersion[64]; ///< 硬件版本信息 char sEncryptVersion[64]; ///< 加密版本信息 SDK_SYSTEM_TIME tmBuildTime;///< 软件创建时间 char sSerialNumber[64]; ///< 设备序列号 int byChanNum; ///< 视频输入通道数 int iVideoOutChannel; ///< 视频输出通道数 int byAlarmInPortNum; ///< 报警输入通道数 int byAlarmOutPortNum; ///< 报警输出通道数 int iTalkInChannel; ///< 对讲输入通道数 int iTalkOutChannel; ///< 对讲输出通道数 int iExtraChannel; ///< 扩展通道数 int iAudioInChannel; ///< 音频输入通道数 int iCombineSwitch; ///< 组合编码通道分割模式是否支持切换 int iDigChannel; ///<数字通道数 unsigned int uiDeviceRunTime; ///<系统运行时间}H264_DVR_DEVICEINFO,*LPH264_DVR_DEVICEINFO;typedef struct H264_DVR_CLIENTINFO{ int nChannel; //通道号 int nStream; //0表示主码流,为1表示子码流 int nMode; //0:TCP方式,1:UDP方式,2:多播方式,3 - RTP方式,4-音视频分开(TCP) int nComType; //只对组合编码通道有效, 组合编码通道的拼图模式 void* hWnd; H264_DVR_CLIENTINFO() { hWnd=0; } }*LPH264_DVR_CLIENTINFO;//服务器断开回调原形typedef void (CALL_METHOD *fDisConnect)(long lLoginID, char *pchDVRIP, long nDVRPort, unsigned long dwUser);//*** */SDK初始化H264_DVR_API long CALL_METHOD H264_DVR_Init(fDisConnect cbDisConnect, unsigned long dwUser);//打开实时预览H264_DVR_API long CALL_METHOD H264_DVR_RealPlay(long lLoginID, LPH264_DVR_CLIENTINFO lpClientInfo);
我调用时候的代码
- C# code
/// <summary> /// 设备信息 /// H264_DVR_DEVICEINFO,*LPH264_DVR_DEVICEINFO; /// </summary> public struct H264_DVR_DEVICEINFO { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] sSoftWareVersion; ///< 软件版本信息 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] sHardWareVersion; ///< 硬件版本信息 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] sEncryptVersion; ///< 加密版本信息 public SDK_SYSTEM_TIME tmBuildTime;///< 软件创建时间 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] sSerialNumber; ///< 设备序列号 public Int32 byChanNum; ///< 视频输入通道数 public Int32 iVideoOutChannel; ///< 视频输出通道数 public Int32 byAlarmInPortNum; ///< 报警输入通道数 public Int32 byAlarmOutPortNum; ///< 报警输出通道数 public Int32 iTalkInChannel; ///< 对讲输入通道数 public Int32 iTalkOutChannel; ///< 对讲输出通道数 public Int32 iExtraChannel; ///< 扩展通道数 public Int32 iAudioInChannel; ///< 音频输入通道数 public Int32 iCombineSwitch; ///< 组合编码通道分割模式是否支持切换 public Int32 iDigChannel; ///<数字通道数 public Int32 uiDeviceRunTime; ///<系统运行时间 } /// <summary> /// *LPH264_DVR_CLIENTINFO; /// </summary> public struct H264_DVR_CLIENTINFO { /// <summary> /// //通道号 /// </summary> public int nChannel; /// <summary> /// //0表示主码流,为1表示子码流 /// </summary> public int nStream; /// <summary> /// //0:TCP方式,1:UDP方式,2:多播方式,3 - RTP方式,4-音视频分开(TCP) /// </summary> public int nMode; /// <summary> /// //只对组合编码通道有效, 组合编码通道的拼图模式 /// </summary> public int nComType; public IntPtr hWnd; //H264_DVR_CLIENTINFO(IntPtr hWnd) //{ // hWnd = IntPtr.Zero; //} } /// <summary> /////服务器断开回调原形 /// typedef void (CALL_METHOD *fDisConnect)(long lLoginID, char *pchDVRIP, long nDVRPort, unsigned long dwUser); /// </summary> public delegate void fDisConnect(int lLoginID, string pchDVRIP, int nDVRPort, uint dwUser); /// <summary> /////*** */SDK初始化 /// H264_DVR_API long CALL_METHOD H264_DVR_Init(fDisConnect cbDisConnect, unsigned long dwUser); /// </summary> [DllImport("netsdk.dll")] public static extern int H264_DVR_Init(fDisConnect cbDisConnect, uint dwUser); /// <summary> /////获取错误信息 /// H264_DVR_API long CALL_METHOD H264_DVR_GetLastError(); /// </summary> [DllImport("netsdk.dll")] public static extern int H264_DVR_GetLastError(); /// <summary> ///向设备注册 ///H264_DVR_API long CALL_METHOD H264_DVR_Login(char *sDVRIP, unsigned short wDVRPort, char *sUserName, char *sPassword,LPH264_DVR_DEVICEINFO lpDeviceInfo, int *error); /// </summary> [DllImport("netsdk.dll")] public static extern int H264_DVR_Login(string sDVRIP, ushort wDVRPort, string sUserName, string sPassword, ref H264_DVR_DEVICEINFO lpDeviceInfo, IntPtr error); /// <summary> ///打开实时预览 ///H264_DVR_API long CALL_METHOD H264_DVR_RealPlay(long lLoginID, LPH264_DVR_CLIENTINFO lpClientInfo); /// </summary> [DllImport("netsdk.dll")] public static extern int H264_DVR_RealPlay(int lLoginID, ref H264_DVR_CLIENTINFO lpClientInfo);
[解决办法]
一般这种问题很可能是参数不对应,仔细检查一下
[解决办法]
字符集的问题吧
[DllImport("netsdk.dll",EntryPoint = "H264_DVR_Init", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
[解决办法]
1、C#中进行结构定义时,须加[StructLayout(LayoutKind.Sequential]
2、fDisConnect回调函数在H264_DVR_Init调用完成后供dll使用,须使用HandleRef或GCHandle避免GC
建议楼主贴出H264_DVR_Init的C#调用相关代码
[解决办法]
把结构换成类试一试,
[解决办法]
C++写的DLL有源代码吗?如果有的话可以将这段代码添加到C#工程中,然后在DLL中设置断点进行调试,这样你就知道问题出在哪了。
[解决办法]
[StructLayoutAttribute(LayoutKind.Sequential)]
结构前加这个, 结构体的子结构自己new出来, 保证回调函数的全局性, 还有把回调置为空试一下。
[解决办法]
C++数据类型与C#对应关系
http://www.cnblogs.com/erwin/archive/2010/04/07/1706032.html