a question about calling unmanged code from managed code

C

chaor

hi,
how to convert the following strut into safe struct in c#?

struct in C++:

typedef struct
{
char m_username[USER_LEN];
char m_password[8];
char m_userIP[16];
}USERPARA,*PUSERPARA;

typedef struct{
char m_starthour;
char m_startmin;
char m_stophour;
char m_stopmin;
}RECORDTIME,*PRECORDTIME;


typedef struct{
ULONG m_alarmsenstive;
ULONG m_detect[18][22];
}DETECTSCOPE,*PDETECTSCOPE;

typedef struct{
RECORDTIME m_recordtime[7][4];
ULONG m_workmode[7][4];
BOOL m_bAllDayRecord[7];
}RECORDPLAN,*PRECORDPLAN;

typedef struct
{
BYTE m_channelName[USER_LEN];
ULONG m_streamType;
ULONG m_encodeType;
ULONG m_videobitrate;
ULONG m_videoFrameRate;
ULONG m_picturequality;
ULONG m_bitratetype;
ULONG m_Iinterval;
ULONG m_brightness;
ULONG m_contrast;
ULONG m_tonality;
ULONG m_saturation;
BOOL m_bRecord;
RECORDPLAN m_recordplan;
DETECTSCOPE m_detectscope;
BOOL m_bSetcommonuser;
ULONG m_delay;
BOOL m_bOsd;
BOOL m_bLogo;
USERPARA m_userpara[6];
ULONG m_userdefinedrate;
}CHANNELPARA,*PCHANNELPARA;



the struct i wrote in c#(but it's wrong)

[ StructLayout( LayoutKind.Sequential)]
public struct USERPARA
{
[MarshalAs(UnmanagedType.ByValArray,SizeConst=GlobalDefine.USER_LEN)]
public char[] m_username;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=8)]
public char[] m_password;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=16)]
public char[] m_userIP;
}

[ StructLayout( LayoutKind.Sequential)]
public struct DETECTSCOPE
{
public long m_alarmsenstive;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=396)]
public long[,] m_detect;
}

[ StructLayout( LayoutKind.Sequential)]
public struct RECORDTIME{
public char m_starthour;
public char m_startmin;
public char m_stophour;
public char m_stopmin;
}

[ StructLayout( LayoutKind.Sequential)]
public struct RECORDPLAN
{
[MarshalAs(UnmanagedType.ByValArray,SizeConst=28)]
public RECORDTIME[,] m_recordtime;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=28)]
public long[,] m_workmode;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=7)]
public bool[] m_bAllDayRecord;
}

[ StructLayout( LayoutKind.Sequential)]
public struct CHANNELPARA
{
[MarshalAs(UnmanagedType.ByValArray,SizeConst=GlobalDefine.USER_LEN)]
public byte[] m_channelName;
public long m_streamType;
public long m_encodeType;
public long m_videobitrate;
public long m_videoFrameRate;
public long m_picturequality;
public long m_bitratetype;
public long m_Iinterval;
public long m_brightness;
public long m_contrast;
public long m_tonality;
public long m_saturation;
public bool m_bRecord;
public RECORDPLAN m_recordplan;
public DETECTSCOPE m_detectscope;
public bool m_bSetcommonuser;
public long m_delay;
public bool m_bOsd;
public bool m_bLogo;
[MarshalAs(UnmanagedType.LPArray,SizeConst=GlobalDefine.USER_LEN)]
public USERPARA[] m_userpara;
public long m_userdefinedrate
}

when i use the struct i wrote in c# it give me the following error:
Additional information: Can not marshal field m_recordplan of type
Hikcoin.SdkWrap.CHANNELPARA: The type definition of this field has no layout
information.

can anybody help me?
thx!!!!
 
P

Peter Morris [Droopy eyes software]

Hi

Firstly, I marshal array of char like so

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
internal String szShortName;


I had the same error. I declared the "pointer to a struct" as IntPtr and
when calling the API I used Marshal.AllocHGlobal, Marshal.StructureToPtr,
Marshal.PtrToStructure....

private Boolean AcmFormatEnumCallBack(Int32 driverID, ref AcmFormatDetails
formatDetails, Int32 instances, Int32 supportFlags)
{
WaveFormatEx waveFormatEx;
waveFormatEx =
(WaveFormatEx)Marshal.PtrToStructure(formatDetails.waveFormatEx,
typeof(WaveFormatEx));
List.Add(new AudioFormat(codec, formatDetails.szFormat, waveFormatEx));
return true;
}

public void Refresh()
{
Boolean driverWasOpen;
IntPtr waveFormatExBuffer;
WaveFormatEx waveFormatEx = new WaveFormatEx();
driverWasOpen = codec.IsOpen;

if (!driverWasOpen)
codec.Open();
waveFormatExBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(waveFormatEx));
try
{
List.Clear();
Marshal.StructureToPtr(waveFormatEx, waveFormatExBuffer, false);
AcmFormatDetails formatDetails = new AcmFormatDetails();
formatDetails.waveFormatEx = waveFormatExBuffer;
formatDetails.dwFormatTag = 0;
formatDetails.waveFormatExBufferSize = Marshal.SizeOf(waveFormatEx);
formatDetails.cbStruct = Marshal.SizeOf(formatDetails);

MsAcm.MMCheck(MsAcm.AcmFormatEnum(codec.Instance, ref formatDetails, new
MsAcm.AcmFormatEnumDelegate(AcmFormatEnumCallBack), 0, 0),
typeof(AudioFormatException), "Error enumerating audio formats for
codec : " + codec.ShortName);
}
finally
{
Marshal.FreeHGlobal(waveFormatExBuffer);
if (!driverWasOpen & codec.IsOpen)
codec.Close();
}
}
 
C

chaor

the condition of the following:

array of char
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
internal String szShortName;

i has solved like:

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
internal char[] szShortName;

but i still don't know how to write the code of
char[,] xxx

....
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top