2014-01-10 177 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,我做了一些改變,它的代碼工作! :) –