将c ++结构转换为struct c#

时间:2014-01-10 01:26:33

标签: c# c++ pinvoke

我将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);

似乎一切正常,但是当我运行该程序时,该方法返回一个非法的参数。

我做错了什么?我认为问题在于转换。

问候。

1 个答案:

答案 0 :(得分:4)

您的C ++ bool是一个字节。但C#bool default marshaling与4字节Winapi BOOL类型相同。您需要为结构中的每个[MarshalAs(UnmanagedType.U1)]添加bool

您使用ushort是错误的。在C ++方面,您有unsigned int。那是C#方面的uint

您还需要准确地翻译结构。也许当你在调试时,pAlarmInfo的长度为64而不是8.显然你需要回去做正确的事。

我猜你做了那个改变,因为结构大小不正确。这应该是一个迹象表明存在更严重的问题。你的结构必须为每个成员排队。你不能只是在末尾添加一堆填充来获得正确的大小。如果尺寸不匹配则布局错误。您可以使布局匹配,从而使尺寸匹配。当后者正确完成后,前者就会发生。