如何解决C# 封送处理 C++ 函数
我正在尝试使用海康威视 SDK https://www.hikvision.com/en/support/download/sdk/ 我目前的目标是用对讲室外站打开门(触发输出)。
我成功登录 (NET_DVR_LoginV40) 并显示室外站的摄像头。
我的下一步是打开门。为此,我需要调用 NET_DVR_RemoteControl 函数,传入 NET_DVR_Control_GateWay 的结构。
现在执行此操作时它不起作用,它返回错误 17,这显然是:
参数错误。 SDK API 中的输入或输出参数为 NULL,或 参数的值或格式与 要求。
因此,我的 C# 代码中几乎 100% 有问题。但我不知道它是什么,据我所知,如果你不是这方面的专家,这是不可能轻易确定的(我不是)
函数的dll导入:
[DllImport(@"..\bin\HCNetSDK.dll")]
public static extern bool NET_DVR_RemoteControl(int lUserID,uint dwCommand,IntPtr lpInBuffer,uint dwInBufferSize);
上一个函数的参数结构体:
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct NET_DVR_Control_GateWay
{
public uint dwSize;
public uint dwGatewayIndex;
public byte byCommand;
public byte byLockType;
public UInt16 wLockID;
[MarshalAsAttribute(UnmanagedType.ByValArray,SizeConst = 32,ArraySubType = UnmanagedType.I1)]
public byte[] byControlSrc;
public byte byControlType;
[MarshalAsAttribute(UnmanagedType.ByValArray,SizeConst = 3,ArraySubType = UnmanagedType.I1)]
public byte[] byRes3;
[MarshalAsAttribute(UnmanagedType.ByValArray,SizeConst = 16,ArraySubType = UnmanagedType.I1)]
public byte[] byPassword;
[MarshalAsAttribute(UnmanagedType.ByValArray,SizeConst = 108,ArraySubType = UnmanagedType.I1)]
public byte[] byRes2;
public void Init()
{
byRes3 = new byte[64];
byRes2 = new byte[108];
}
}
我的开门方法:
private void button_Door1_Click(object sender,EventArgs e)
{
CHCNetSDK.NET_DVR_Control_GateWay gateWay = new CHCNetSDK.NET_DVR_Control_GateWay();
gateWay.Init();
gateWay.dwSize = (uint)Marshal.SizeOf(gateWay);
gateWay.dwGatewayIndex = 1;
gateWay.byCommand =1; //opening command
gateWay.byLockType = 0 ; //this is a normal lock not a smart lock
gateWay.wLockID = 0; //this is 0 because I want to use the door station's output
gateWay.byControlSrc = new byte[] {123} ; // this needs to be something,but doesn't matter what
gateWay.byControlType = 1 ; //this needs to be 1 or 2 but does not matter which
//gateWay.byPassword = ; this is not needed because the LockType is 0
IntPtr ptrStruData = Marshal.AllocHGlobal((int)gateWay.dwSize);
var dd = CHCNetSDK.NET_DVR_RemoteControl(lUserID,16009,ptrStruData,gateWay.dwSize);
MessageBox.Show(dd.ToString() + CHCNetSDK.NET_DVR_GetLastError().ToString() + "\n" + gateWay.dwSize.ToString() + "\n" + "ptrStruData:" + ptrStruData.ToString());
}
According to the documentation the function looks like this
And the struct is defined as such
所以据我所知,我已经正确地完成了定义和导入。
如果有人能让我朝着正确的方向前进,我将不胜感激,因为我以前从未使用过 C#、C++ 互操作,此时我不知道如何继续,如何调试,如何确定问题在我的代码中。
我已尝试就此问题与制造商联系,但他们无法直接帮助我解决代码,从他们的角度来看,一切正常,因为我得到错误是我是问题的原因。
非常感谢您的帮助!
解决方法
您使用 Marshal.AllocHGlobal
分配了一些内存,您没有将 gateWay
结构复制到该内存中,而是将指向已分配内存的指针传递给 NET_DVR_RemoteControl
以便它看到 {{3 }},然后你不释放分配的内存,使其泄漏。
您可以通过 random garbage gateWay
将其修复到分配的内存中,然后在调用后 copying 修复它。
然而,最好让编组器完成它的工作:
[DllImport(HIKVISION_LIBRARY,CallingConvention = CallingConvention.StdCall,CharSet = CharSet.Ansi,ExactSpelling = true,SetLastError = false)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool NET_DVR_RemoteControl(int lUserID,int dwCommand,[In] ref NET_DVR_CONTROL_GATEWAY lpInBuffer,int dwInBufferSize);
[StructLayout(LayoutKind.Sequential,Pack = 1)]
public struct NET_DVR_CONTROL_GATEWAY
{
public int dwSize;
public int dwGatewayIndex;
public byte byCommand;
public byte byLockType;
public short wLockID;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst = NAME_LEN)]
public string byControlSrc;
public byte byControlType;
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 3)]
public byte[] byRes3;
[MarshalAs(UnmanagedType.ByValTStr,SizeConst = PASSWD_LEN)]
public string byPassword;
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 108)]
public byte[] byRes2;
}
var gateWay = new NET_DVR_CONTROL_GATEWAY()
{
dwSize = Marshal.SizeOf<NET_DVR_CONTROL_GATEWAY>(),dwGatewayIndex = 1,byCommand = 1,byLockType = 0,wLockID = 0,byControlType = 1
};
var dd = NET_DVR_RemoteControl(lUserID,16009,ref gateWay,gateWay.dwSize);
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。