我将struct c ++转换为c#struct有问题,我将留下以下代码:
C ++
struct SDK_ALARM_INPUTCONFIG
{
bool bEnable;
int iSensorType;
SDK_EventHandler hEvent;
};
struct SDK_EventHandler
{
unsigned int dwRecord;
int iRecordLatch;
unsigned int dwTour;
unsigned int dwSnapShot;
unsigned int dwAlarmOut;
unsigned int dwMatrix;
int iEventLatch;
int iAOLatch;
SDK_PtzLinkConfig PtzLink[NET_MAX_CHANNUM];
SDK_CONFIG_WORKSHEET schedule;
bool bRecordEn;
bool bTourEn;
bool bSnapEn;
bool bAlarmOutEn;
bool bPtzEn;
bool bTip;
bool bMail;
bool bMessage;
bool bBeep;
bool bVoice;
bool bFTP;
bool bMatrixEn;
bool bLog;
bool bMessagetoNet;
bool bShowInfo;
unsigned int dwShowInfoMask;
char pAlarmInfo[8];
bool bShortMsg;
bool bMultimediaMsg;
};
struct SDK_PtzLinkConfig
{
int iType;
int iValue;
};
struct SDK_CONFIG_WORKSHEET
{
SDK_TIMESECTION tsSchedule[6][7];
};
struct SDK_TIMESECTION
{
int enable;
int startHour;
int startMinute;
int startSecond;
int endHour;
int endMinute;
int endSecond;
};
C#:
[StructLayout(LayoutKind.Sequential)]
public struct SDK_ALARM_INPUTCONFIG
{
public bool bEnable;
public int iSensorType;
public SDK_EventHandler hEvent;
};
[StructLayout(LayoutKind.Sequential)]
public struct SDK_EventHandler
{
public ushort dwRecord;
public int iRecordLatch;
public ushort dwTour;
public ushort dwSnapShot;
public ushort dwAlarmOut;
public ushort dwMatrix;
public int iEventLatch;
public int iAOLatch;
[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.Struct, SizeConst = 32)]
public SDK_PtzLinkConfig[] PtzLink;
public SDK_CONFIG_WORKSHEET schedule;
public bool bRecordEn;
public bool bTourEn;
public bool bSnapEn;
public bool bAlarmOutEn;
public bool bPtzEn;
public bool bTip;
public bool bMail;
public bool bMessage;
public bool bBeep;
public bool bVoice;
public bool bFTP;
public bool bMatrixEn;
public bool bLog;
public bool bMessagetoNet;
public bool bShowInfo;
public ushort dwShowInfoMask;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
public string pAlarmInfo;
//public bool bShortMsg;
//public bool bMultimediaMsg;
};
[StructLayout(LayoutKind.Sequential)]
public struct SDK_PtzLinkConfig
{
public int iType;
public int iValue;
};
[StructLayout(LayoutKind.Sequential)]
public struct SDK_CONFIG_WORKSHEET
{
[MarshalAs(UnmanagedType.ByValArray, ArraySubType=UnmanagedType.Struct, SizeConst = 6*7)]
public SDK_TIMESECTION[] tsSchedule;
};
[StructLayout(LayoutKind.Sequential)]
struct SDK_TIMESECTION
{
public int enable;
public int startHour;
public int startMinute;
public int startSecond;
public int endHour;
public int endMinute;
public int endSecond;
};
我打电话给这个方法:
C ++:
long H264_DVR_GetDevConfig(long lLoginID, unsigned long dwCommand, int nChannelNO, char * lpOutBuffer, unsigned long dwOutBufferSize, unsigned long* lpBytesReturned,int waittime = 1000);
C#:
[DllImport("NetSdk.dll")]
public static extern int H264_DVR_GetDevConfig(int lLoginID, uint dwCommand, int nChannelNO, IntPtr lpOutBuffer,
uint dwOutBufferSize, ref uint lpBytesReturned, int waittime);
我这样打电话:
C#:
var vAlarmConfig = new SDK_ALARM_INPUTCONFIG();
IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SDK_ALARM_INPUTCONFIG)));
Marshal.StructureToPtr(vAlarmConfig, ptr, true);
uint lpBytesReturned = (uint)Marshal.SizeOf(typeof(SDK_ALARM_INPUTCONFIG));
int CHANNEL = 2;
int result = XMSDK.H264_DVR_GetDevConfig(lLoginID, (uint)SDK_CONFIG_TYPE.E_SDK_CONFIG_ALARM_IN, CHANNEL, ptr,
(uint)Marshal.SizeOf(typeof(SDK_ALARM_INPUTCONFIG)), ref lpBytesReturned, 10000);
似乎一切正常,但是当我运行该程序时,该方法返回一个非法的参数。
我做错了什么?我认为问题在于转换。
问候。
答案 0 :(得分:4)
您的C ++ bool
是一个字节。但C#bool
default marshaling与4字节Winapi BOOL
类型相同。您需要为结构中的每个[MarshalAs(UnmanagedType.U1)]
添加bool
。
您使用ushort
是错误的。在C ++方面,您有unsigned int
。那是C#方面的uint
。
您还需要准确地翻译结构。也许当你在调试时,pAlarmInfo
的长度为64而不是8.显然你需要回去做正确的事。
我猜你做了那个改变,因为结构大小不正确。这应该是一个迹象表明存在更严重的问题。你的结构必须为每个成员排队。你不能只是在末尾添加一堆填充来获得正确的大小。如果尺寸不匹配则布局错误。您可以使布局匹配,从而使尺寸匹配。当后者正确完成后,前者就会发生。