-
November 14th, 2013, 10:20 AM
#1
[RESOLVED] Wrapper from C++ to C#
Hi all,
I'm Marco and I'm a .NET software developer. I'm developing a C# console application based on a C++ set of DLLs using the DllImport attribute.
The C++ DLLs are part of a Video Management System SDK developed by a third part.
Following you'll find a piece of code that I wrote but that's not work properly:
Code:
[DllImport("TruVNetSDK.dll")]
public static extern int NET_DVR_Login_V30(string sDVRIP, int wDVRPort, string sUserName, string sPassword, out LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo);
public struct LPNET_DVR_DEVICEINFO_V30
{
public byte sSerialNumber;
public byte byAlarmInPortNum;
public byte byAlarmOutPortNum;
public byte byDiskNum;
public byte byChanNum;
public byte byStartChan; }
public void LogOn()
{
LPNET_DVR_DEVICEINFO_V30 _info;
NET_DVR_Login_V30("ip_address", port_number, "username", "password", out _info); }
And following the documentation provided by the third part developer team about the "NET_DVR_Login_V30" function and the "LPNET_DVR_DEVICEINFO_V30" struct:
LONG NET_DVR_Login_V30 (char *sDVRIP, WORD wDVRPort, char *sUserName, char *sPassword, LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo)
Parameters:
sDVRIP
[in] IP address of the DVR
wServerPort
[in] Port NO. of the DVR
sUserName
[in] User's name
sPassword
[in] Password
lpDeviceInfo
[out] Information of device
struct{
BYTE sSerialNumber[SERIALNO_LEN];
BYTE byAlarmInPortNum;
BYTE byAlarmOutPortNum;
BYTE byDiskNum;
BYTE byChanNum;
BYTE byStartChan;
}NET_DVR_DEVICEINFO,*LPNET_DVR_DEVICEINFO;
Members:
sSerialNumber
Serial NO.
byAlarmInPortNum
The number of alarm input
byAlarmOutPortNum
The number of alarm output
byDiskNum
The number of hard disks
byChanNum
The number of analog channels
byStartChan
Start number of channel, start from 1 currently.
The problem is that I don't understand what kind of values are stored in the "_info" struct:
_info.sSerialNumber = 86
_info.byAlarmInPortNum = 82
_info.byAlarmOutPortNum = 48
_info.byDiskNum = 49
_info.byChanNum = 56
_info.byStartChan = 84
These values are not correct, the real values should be:
TVR11080820121218BBRR090016095WCVU
4
1
1
8
1
What's wrong?
Thank you a lot
-
November 14th, 2013, 12:07 PM
#2
Re: Wrapper from C++ to C#
You need to change your marshalling a bit.
Code:
public static extern int NET_DVR_Login_V30(string sDVRIP, int wDVRPort, string sUserName, string sPassword, out LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo);
public struct LPNET_DVR_DEVICEINFO_V30
{
public byte sSerialNumber;
public byte byAlarmInPortNum;
public byte byAlarmOutPortNum;
public byte byDiskNum;
public byte byChanNum;
public byte byStartChan;}
Should be something more like:
Code:
public static extern int NET_DVR_Login_V30([In][MarshalAs(UnmanagedType.LPWStr)] string sDVRIP, int wDVRPort, [In][MarshalAs(UnmanagedType.LPWStr)] string sUserName, [In][MarshalAs(UnmanagedType.LPWStr)] string sPassword, ref LPNET_DVR_DEVICEINFO_V30 lpDeviceInfo);
public struct LPNET_DVR_DEVICEINFO_V30
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)] // set to SERIALNO_LEN
public string sSerialNumber;
[MarshalAs(UnmanagedType.U1)]
public byte byAlarmInPortNum;
[MarshalAs(UnmanagedType.U1)]
public byte byAlarmOutPortNum;
[MarshalAs(UnmanagedType.U1)]
public byte byDiskNum;
[MarshalAs(UnmanagedType.U1)]
public byte byChanNum;
[MarshalAs(UnmanagedType.U1)]
public byte byStartChan;}
-
November 14th, 2013, 12:25 PM
#3
Re: Wrapper from C++ to C#
Great Tron it's working!
I think that I will study the MarshalAs attribute
-
November 18th, 2013, 11:06 AM
#4
Re: Wrapper from C++ to C#
Hi guys,
now I'm struggling to make work properly another function, following my piece of code:
Code:
[DllImport("TruVNetSDK.dll")]
public static extern bool NET_DVR_CaptureJPEGPicture(int lUserID, int lChannel, LPNET_DVR_JPEGPARA lpJpegPara, [In][MarshalAs(UnmanagedType.LPWStr)] string sPicFileName);
public struct LPNET_DVR_JPEGPARA
{
[MarshalAs(UnmanagedType.U2)]
public ushort wPicSize;
[MarshalAs(UnmanagedType.U2)]
public ushort wPicQuality; }
public bool CaptureJPEGPicture(int userId, int channelNumber)
{
LPNET_DVR_JPEGPARA param = new LPNET_DVR_JPEGPARA();
param.wPicSize = 0; // VGA
param.wPicQuality = 2; // best quality
return NET_DVR_CaptureJPEGPicture(userId, channelNumber, param, "D:\test.jpeg"); }
Following the SDK documentation:
BOOL NET_DVR_CaptureJPEGPicture(LONG lUserID, LONG lChannel, LPNET_DVR_JPEGPARA lpJpegPara, char *sPicFileName)
Parameters:
lUserID
[in] The return value of NET_DVR_Login_V30
lChannel
[in] Channel number
lpJpegPara
[in] JPEG image parameter
sPicFileName
[in] URL of JPEG file
Structure of JPEG picture parameters
struct{
WORD wPicSize;
WORD wPicQuality;
}NET_DVR_JPEGPARA,*LPNET_DVR_JPEGPARA;
Members
wPicSize
Size of picture: 0-CIF, 1-QCIF, 2-D1, 3-UXGA, 4-SVGA, 5-HD720p, 6-VGA, 7-XVGA, 8-HD900p, 9-HD1080, 10-2560*1920, 11-1600*304, 12-2048*1536, 13-2448*2048
wPicQuality
Picture quality: 0- best, 1- better, 2- average
When I call CaptureJPEGPicture() an exception is thrown:
"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
Why this error?
Thank you a lot!
Marco
-
November 18th, 2013, 11:55 AM
#5
Re: Wrapper from C++ to C#
The first method works because you are receiving the structure from the API so a pointer will do the trick.
To send structures to the API you'll have to do more.
Something like this:
Code:
IntPtr pStruct = Marshal.AllocCoTaskMem(structureSize);
if (null != pStruct )
{
Marshal.Copy(myStruct, 0, pStruct , structureSize);
// use pStruct
Marshal.FreeCoTaskMem(pStruct);
}
-
November 18th, 2013, 01:20 PM
#6
Re: Wrapper from C++ to C#
Actually in your case you most likely need the following line instead of Marshal.Copy().
Code:
Marshal.StructureToPtr(myStruct, pStruct, false)
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|