gpt4 book ai didi

c# - C SDK转C#时出现非法参数

转载 作者:太空宇宙 更新时间:2023-11-03 23:51:34 29 4
gpt4 key购买 nike

我正在尝试将 C SDK 转换为 C#,但在转换 C 函数时遇到“非法参数”错误。

C SDK函数的详细信息如下所示

#ifndef LLONG
#ifdef WIN32
#define LLONG LONG
#else //WIN64
#define LLONG INT64
#endif
#endif

#ifndef CLIENT_API
#define CLIENT_API __declspec(dllexport)
#endif

#else

#ifndef CLIENT_API
#define CLIENT_API __declspec(dllimport)
#endif

#endif

#define CALLBACK __stdcall
#define CALL_METHOD __stdcall //__cdecl


// Configuration type,corresponding to CLIENT_GetDevConfig and CLIENT_SetDevConfig
#define DH_DEV_DEVICECFG 0x0001 // Device property setup
#define DH_DEV_NETCFG 0x0002 // Network setup
#define DH_DEV_CHANNELCFG 0x0003 // Video channel setup
#define DH_DEV_PREVIEWCFG 0x0004 // Preview parameter setup
#define DH_DEV_RECORDCFG 0x0005 // Record setup
#define DH_DEV_COMMCFG 0x0006 // COM property setup
#define DH_DEV_ALARMCFG 0x0007 // Alarm property setup
#define DH_DEV_TIMECFG 0x0008 // DVR time setup
#define DH_DEV_TALKCFG 0x0009 // Audio talk parameter setup
#define DH_DEV_AUTOMTCFG 0x000A // Auto matrix setup
#define DH_DEV_VEDIO_MARTIX 0x000B // Local matrix control strategy setup
#define DH_DEV_MULTI_DDNS 0x000C // Multiple ddns setup
#define DH_DEV_SNAP_CFG 0x000D // Snapshot corresponding setup
#define DH_DEV_WEB_URL_CFG 0x000E // HTTP path setup
#define DH_DEV_FTP_PROTO_CFG 0x000F // FTP upload setup
#define DH_DEV_INTERVIDEO_CFG 0x0010 // Plaform embedded setup. Now the channel parameter represents the platform type.



// Search configuration information
CLIENT_API BOOL CALL_METHOD CLIENT_GetDevConfig(LLONG lLoginID, DWORD dwCommand, LONG lChannel, LPVOID lpOutBuffer, DWORD dwOutBufferSize, LPDWORD lpBytesReturned,int waittime=500);

C#信息如下:

//  [DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.StdCall)]
[DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.Cdecl)]
// [DllImport("dhnetsdk.dll")]

public static extern bool CLIENT_GetDevConfig(long lLoginID,
uint dwCommand,
long lChannel,
IntPtr lpBuffer,
uint dwOutBufferSize,
uint lpBytesReturned,
int waittime = 500);

我调用的方法如下:

int t = 500;
uint BytesReturned = 0;
uint c = 8;

var lpOutBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(NET_TIME)));
if (CLIENT_GetDevConfig(lLogin, c, 0, lpOutBuffer, (uint)Marshal.SizeOf(typeof(NET_TIME)), BytesReturned, t) == false)
{
Console.WriteLine("GetDevConfig FAILED");
}


[StructLayout(LayoutKind.Sequential)]
public struct NET_TIME
{
// [FieldOffset(0)]
uint dwYear;
// [FieldOffset(4)]
uint dwMonth;
// [FieldOffset(4)]
uint dwDay;
// [FieldOffset(4)]
uint dwHour;
// [FieldOffset(4)]
uint dwMinute;
// [FieldOffset(4)]
uint dwSecond;
}

我肯定 lLogin 是正确的,因为我使用它成功登录到设备。但是当我在调用 GetDevConfig 失败后立即检查 GetLastError 时,它指示非法参数。那么,有人能指出上面代码中的非法参数吗?

以下是我的C#代码,有非法参数问题...

using System;
using System.Runtime.InteropServices;

class PlatformInvokeTest
{
static public int lLogin;

public delegate void fDisConnect(long lLoginID, IntPtr pchDVRIP, long nDVRPort, uint dwUser);
public delegate void fHaveReConnect(long lLoginID, IntPtr pchDVRIP, long nDVRPort, uint dwUser);

[DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool CLIENT_Init(fDisConnect cbDisConnect, uint dwUser);

[DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void CLIENT_SetAutoReconnect(fHaveReConnect cbHaveReconnt, uint dwUser);

[DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern int CLIENT_Login(string pchDVRIP, ushort wDVRPort, string pchUserName, string pchPassword, NET_DEVICEINFO lpDeviceInfo, IntPtr error);

[DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CLIENT_GetDevConfig(
int loginId,
uint command,
int channel,
out NET_TIME buffer,
out uint bufferSize,
IntPtr lpBytesReturned,
int waittime = 500);

[DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool CLIENT_Logout(long lID);

[DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void CLIENT_Cleanup();

[DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern uint CLIENT_GetLastError();


public static void fDisConnectMethod(long lLoginID, IntPtr pchDVRIP, long nDVRPort, uint dwUser)
{
System.Console.WriteLine("Disconnect");
return;
}

public static void fHaveReConnectMethod(long lLoginID, IntPtr pchDVRIP, long nDVRPort, uint dwUser)
{
System.Console.WriteLine("Reconnect success");
return;
}

[StructLayout(LayoutKind.Sequential)]
public class NET_DEVICEINFO
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] sSerialNumber;
public byte byAlarmInPortNum;
public byte byAlarmOutPortNum;
public byte byDiskNum;
public byte byDVRType;
public byte byChanNum;
}

[StructLayout(LayoutKind.Sequential)]
public struct NET_TIME
{
uint dwYear;
uint dwMonth;
uint dwDay;
uint dwHour;
uint dwMinute;
uint dwSecond;
}

public static void Main()
{
fDisConnect fDisConnecthandler = fDisConnectMethod;
fHaveReConnect fHaveReConnecthandler = fHaveReConnectMethod;
NET_DEVICEINFO deviceinfo = new NET_DEVICEINFO();
IntPtr iRet = new IntPtr(0);
CLIENT_Init(fDisConnectMethod, 0);
CLIENT_SetAutoReconnect(fHaveReConnecthandler, 0);
lLogin = CLIENT_Login("192.168.1.198", 31111, "user", "password", deviceinfo, iRet);

if (lLogin <= 0)
Console.WriteLine("Login device failed");
else
{
Console.WriteLine("Login device successful");
byte[] byteout = new byte[20];
const int t = 500;
IntPtr BytesReturned;
BytesReturned = IntPtr.Zero;
const uint c = 8;
NET_TIME nt;
uint sizeofnt = (uint)Marshal.SizeOf(typeof(NET_TIME));
if (CLIENT_GetDevConfig(lLogin, c, 0, out nt, out sizeofnt, BytesReturned, t) == false)
{
uint gle = CLIENT_GetLastError();
Console.WriteLine("getDevConfig failed");
}
CLIENT_Logout(lLogin);
CLIENT_Cleanup();
}
}
}

这是我尝试移植到 C# 的 C 代码。它工作没有任何问题..

#pragma comment(lib,"dhnetsdk.lib")

#include <Windows.h>
#include <stdio.h>
#include <conio.h>
#include "dhnetsdk.h"

void CALLBACK DisConnectFunc(LONG lLoginID, char *pchDVRIP, LONG nDVRPort, DWORD dwUser)
{
printf("Disconnect.");
return;
}

void CALLBACK AutoConnectFunc(LONG lLoginID,char *pchDVRIP,LONG nDVRPort,DWORD dwUser)
{
printf("Reconnect success.");
return;
}

int main(void)
{
NET_TIME nt = {0};
NET_DEVICEINFO deviceInfo = {0};
unsigned long lLogin = 0;
LPVOID OutBuffer;
int iRet = 0;
DWORD dwRet = 0;

//Initialize the SDK, set the disconnection callback functions
CLIENT_Init(DisConnectFunc,0);
//Setting disconnection reconnection success of callback functions. If don't call this interface, the SDK will not break reconnection.
CLIENT_SetAutoReconnect(AutoConnectFunc,0);
lLogin = CLIENT_Login("192.168.1.108",31111,"user","password",&deviceInfo, &iRet);
if(lLogin <= 0)
{
printf("Login device failed");
}
else
{
OutBuffer = (LPVOID)malloc(sizeof(NET_TIME));
memset(OutBuffer, 0, sizeof(NET_TIME));
if(CLIENT_GetDevConfig( lLogin, 8 /* DH_DEV_TIMECFG */, 0, OutBuffer, sizeof(NET_TIME), &dwRet, 500) == FALSE)
{
printf("Failed\n");
}
else
{
memcpy(&nt, OutBuffer, sizeof(nt));




printf("Time %d %d %d %d %d %d\n", nt.dwYear,nt.dwMonth,nt.dwDay, nt.dwHour,nt.dwMinute, nt.dwSecond);
}
_getch();
}
CLIENT_Logout(lLogin);
CLIENT_Cleanup();
return 0;
}

最佳答案

您的 extern 函数定义有误。让我们以您的 C 调用为例。

// Search configuration information 
CLIENT_API BOOL CALL_METHOD CLIENT_GetDevConfig(LLONG lLoginID, DWORD dwCommand, LONG lChannel, LPVOID lpOutBuffer, DWORD dwOutBufferSize, LPDWORD lpBytesReturned,int waittime=500);

如您帖子的评论所述,LONG 的长度在 Win32 中为 32 位,因此您必须使用 int。您还可以使用关键字 out 来获取您的结构,而无需手动使用 Mashaller。我会这样定义你的功能。

[DllImport("dhnetsdk.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CLIENT_GetDevConfig(int loginId, uint command, int channel, out NET_TIME buffer, out uint bufferSize, IntPtr lpBytesReturned, int waittime = 500);

请注意附加属性 MarshalAs 的存在。它指示托管代码应如何考虑 pinvoke 函数的返回值。

关于c# - C SDK转C#时出现非法参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18923200/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com