2014-01-10 123 views
2

我有转换一个struct C++到C#结构有问题,我会留下下面的代码:转换C++结构,以结构C#

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

'int'可能意味着不同的事情取决于您的C平台/编译器/设置。你需要从弄清楚这里的含义开始。 –

+0

我基于我的代码从一个例子,他们有INT(C++)作为INT(C#),我证明了一些方法在我的C#代码和除此之外的一切工作。 –

+0

@JonathanWood号在Windows上,'int'在C#和C++中是相同的。 –

回答

4

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

您使用ushort是错误的。在C++端你有unsigned int。那就是C#端的uint

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

我想你做了这个改变,因为结构大小不正确。这应该是一个迹象表明存在更严重的问题。你的结构必须为每个成员排队。你不能只是在最后加上一个填充负载来获得正确的大小。如果尺寸不匹配,则布局将错误。由于布局匹配,您可以调整尺寸。当后者正确完成时,前者会作为结果发生。

+0

好吧,我会做的改变,顺便说一下,pAlarmInfo是64而不是8,我的错误。 –

+0

谢谢你帮助我,你是对的,我改变了usint us uort,我做了一些改变,它的代码工作! :) –