首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

C#调用C++写的dll有关问题

2012-04-08 
C#调用C++写的dll问题有个C++写的视频服务器的SDK,需要在C#下调用,但是改来改去总是有问题,无法正确采集图

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

热点排行