i have a problem with convert a struct c++ to c# struct, i will leave the following code:
我有一个问题,将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;
};
I'm calling this method:
我叫这个方法:
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);
I'm calling this way:
我是这样打电话的:
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);
Seems everything work fine, but when i run the program, the method return an illegal paramater.
似乎一切正常,但是当我运行程序时,该方法返回一个非法的参数。
What i'm doing wrong?. I think the problem is the conversion.
我做错了什么?我认为问题在于转换。
Regards.
1 个解决方案
#1
4
Your C++ bool
is a single byte. But the C# bool
default marshaling is as the 4 byte Winapi BOOL
type. You'll need to add [MarshalAs(UnmanagedType.U1)]
for every bool
in your structs.
你的C ++ bool是一个单字节。但是C#bool默认编组是4字节的Winapi BOOL类型。您需要为结构中的每个bool添加[MarshalAs(UnmanagedType.U1)]。
Your use of ushort
is wrong. On the C++ side you have unsigned int
. That is uint
on the C# side.
你使用ushort是错误的。在C ++方面,你有unsigned int。这是在C#方面的结果。
You will also need to translate the structs accurately. Perhaps while you were debugging you made pAlarmInfo
have length 64 rather than 8. Obviously you need to go back an do that correctly.
您还需要准确地翻译结构。也许当你在调试时,你使得pAlarmInfo的长度为64而不是8.显然你需要回去做正确的事情。
I guess you made that change because the struct size was incorrect. That should have been a tell-tale sign that there was a more serious problem. Your structs have to line up for each and every member. You can't just add a load of padding at the end to get the size right. If the sizes don't match then the layout will be wrong. You make the sizes match as a consequence of making the layouts match. When the latter is done correctly, the former happens as a consequence.
我猜你做了那个改变,因为结构大小不正确。这应该是一个迹象表明存在更严重的问题。你的结构必须为每个成员排队。你不能只是在末尾添加一堆填充来获得正确的大小。如果尺寸不匹配则布局错误。由于布局匹配,您可以使大小匹配。当后者正确完成后,前者就会发生。
#1
4
Your C++ bool
is a single byte. But the C# bool
default marshaling is as the 4 byte Winapi BOOL
type. You'll need to add [MarshalAs(UnmanagedType.U1)]
for every bool
in your structs.
你的C ++ bool是一个单字节。但是C#bool默认编组是4字节的Winapi BOOL类型。您需要为结构中的每个bool添加[MarshalAs(UnmanagedType.U1)]。
Your use of ushort
is wrong. On the C++ side you have unsigned int
. That is uint
on the C# side.
你使用ushort是错误的。在C ++方面,你有unsigned int。这是在C#方面的结果。
You will also need to translate the structs accurately. Perhaps while you were debugging you made pAlarmInfo
have length 64 rather than 8. Obviously you need to go back an do that correctly.
您还需要准确地翻译结构。也许当你在调试时,你使得pAlarmInfo的长度为64而不是8.显然你需要回去做正确的事情。
I guess you made that change because the struct size was incorrect. That should have been a tell-tale sign that there was a more serious problem. Your structs have to line up for each and every member. You can't just add a load of padding at the end to get the size right. If the sizes don't match then the layout will be wrong. You make the sizes match as a consequence of making the layouts match. When the latter is done correctly, the former happens as a consequence.
我猜你做了那个改变,因为结构大小不正确。这应该是一个迹象表明存在更严重的问题。你的结构必须为每个成员排队。你不能只是在末尾添加一堆填充来获得正确的大小。如果尺寸不匹配则布局错误。由于布局匹配,您可以使大小匹配。当后者正确完成后,前者就会发生。