-
December 6th, 2013, 05:26 AM
#1
C++ callback to C#
Hi all,
I need to create a C++ callback call in C#.
Following the third part SDK documentation:
DVR_GetCameraInfo(HSERVER hServer, LPST_CAMERA_INFO lpstCameraInfo);
ST_CAMERA_INFO
This data type contains information relevant to a camera.
typedef struct _tagCameraInfo
{
LPVOIDlpfnCameraCallback; }ST_CAMERA_INFO,FAR * LPST_CAMERA_INFO;
lpfnCameraInfoCallback: The address of the returning a result of a callback.
DVR_ONCAMERACALLBACK
A callback function that is called automatically when a client request camera information.
VOID DVR_OnCameraCallback(HSERVER hServer, LPST_EACH_CAMERA_INFO lpstEachCameraInfo);
hServer: (out) A connected server handle.
lpstEachCameraInfo: (out) Information regarding a specific camera. Please refer to ST_EACH_CAMERA_INFO in the 'Data Types' section for more details.
ST_EACH_CAMERA_INFO
This data type contains information relevant to a camera.
typedef struct _tagEachCameraInfo
{
CHAR szCamName[32];
WORD wWidth;
WORD wHeight;
BYTE byFramerate;
BYTE bySchedule;
BYTE byQuality;
BYTE byAudio;
BYTE byVideoStandard;
BYTE byCovert;
BYTE byPTZ;
BYTE byVideoLoss;
INT nAlarmIn;
INT nAlarmOut; }ST_EACH_CAMERA_INFO,FAR *LPST_EACH_CAMERA_INFO;
Following my C# wrapper:
Code:
public static class SDKInterop
{
[StructLayout(LayoutKind.Sequential)]
public struct ST_CAMERA_INFO
{
public DVR_OnCameraCallback lpfnCameraCallback; }
[StructLayout(LayoutKind.Sequential)]
public struct ST_EACH_CAMERA_INFO
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public char[] szCamName;
public ushort wWidth;
public ushort wHeight;
public byte byFramerate;
public byte bySchedule;
public byte byQuality;
public byte byAudio;
public byte byVideoStandard;
public byte byCovert;
public byte byPTZ;
public byte byVideoLoss;
public int nAlarmIn;
public int nAlarmOut; }
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DVR_OnCameraCallback(out UIntPtr hServer, out ST_EACH_CAMERA_INFO lpstEachCameraInfo);
[DllImport(NETWORKCLIENT_DLL_LOCATION, CallingConvention = CallingConvention.Cdecl)]
public static extern Int32 DVR_GetCameraInfo(UIntPtr hServer, ref ST_CAMERA_INFO lpstCameraInfo); }
Following the function calls:
Code:
SDKInterop.ST_CAMERA_INFO _cameraInfo;
_cameraInfo.lpfnCameraCallback = (hS, cI) =>
{
// some code };
int success = SDKInterop.DVR_GetCameraInfo(_hServer, ref _cameraInfo);
Unfortunately it doesn't work because an error message from _cameraInfo.lpfnCameraCallback tells: "Parameter 1 must be declared with the 'out' keyword".
Please could you help me?
Thank you,
Marco
-
December 6th, 2013, 11:10 AM
#2
Re: C++ callback to C#
change 'out' to 'ref'. Output parameters are not passed by reference.
Hope this helps
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rich Cook
0100 1101 0110 1001 0110 0011 0110 1000 0110 0001 0110 0101 0110 1100 0010 0000 0100 0101 0110 1100 0110 1100 0110 0101 0111 0010
-
December 6th, 2013, 11:23 AM
#3
Re: C++ callback to C#
Originally Posted by HairyMonkeyMan
change 'out' to 'ref'. Output parameters are not passed by reference.
Hope this helps
Do you mean something like this?
Code:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DVR_OnCameraCallback(ref UIntPtr hServer, ref ST_EACH_CAMERA_INFO lpstEachCameraInfo);
Visual Studio returns error on:
Code:
_cameraInfo.lpfnCameraCallback = (hS, cI) =>
{
// some code };
-
December 6th, 2013, 11:26 AM
#4
Re: C++ callback to C#
can you upload a repro in a zip?
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rich Cook
0100 1101 0110 1001 0110 0011 0110 1000 0110 0001 0110 0101 0110 1100 0010 0000 0100 0101 0110 1100 0110 1100 0110 0101 0111 0010
-
December 6th, 2013, 04:19 PM
#5
Re: C++ callback to C#
did you try changing the definition of...
Code:
public static extern Int32 DVR_GetCameraInfo(UIntPtr hServer, ref ST_CAMERA_INFO lpstCameraInfo);
to
Code:
public static extern Int32 DVR_GetCameraInfo(out UIntPtr hServer, out ST_CAMERA_INFO lpstCameraInfo);
-
December 9th, 2013, 04:11 AM
#6
Re: C++ callback to C#
Originally Posted by sotoasty
did you try changing the definition of...
Code:
public static extern Int32 DVR_GetCameraInfo(UIntPtr hServer, ref ST_CAMERA_INFO lpstCameraInfo);
to
Code:
public static extern Int32 DVR_GetCameraInfo(out UIntPtr hServer, out ST_CAMERA_INFO lpstCameraInfo);
Yes I've tried also with your code but I don't know how to call:
Code:
_cameraInfo.lpfnCameraCallback = (hS, cI) =>
{
// some code
};
@HairyMonkeyMan
Following a repro zip (rename to .zip):
ConsoleApplication1.doc
Thanks
-
December 9th, 2013, 05:34 AM
#7
Re: C++ callback to C#
Hi Marco,
I changed the DVR_OnCameraCallback delegate in Interop.cs as follows;
Code:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DVR_OnCameraCallback(UIntPtr hServer, ST_EACH_CAMERA_INFO lpstEachCameraInfo);
If I put a breakpoint inside the callback on Server.cs I can see it being hit.
Does this solve it?
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rich Cook
0100 1101 0110 1001 0110 0011 0110 1000 0110 0001 0110 0101 0110 1100 0010 0000 0100 0101 0110 1100 0110 1100 0110 0101 0111 0010
-
December 9th, 2013, 05:49 AM
#8
Re: C++ callback to C#
Originally Posted by HairyMonkeyMan
Hi Marco,
I changed the DVR_OnCameraCallback delegate in Interop.cs as follows;
Code:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DVR_OnCameraCallback(UIntPtr hServer, ST_EACH_CAMERA_INFO lpstEachCameraInfo);
If I put a breakpoint inside the callback on Server.cs I can see it being hit.
Does this solve it?
Great HairyMonkeyMan,
the callback is working!
If I watch into cI object, I see that the values are wrong but the struct ST_EACH_CAMERA_INFO in the Interop class seems to be correct.
I receive something like this:
What do you think?
Thanks
Marco
-
December 9th, 2013, 06:41 AM
#9
Re: C++ callback to C#
try defining your struct as follows:
Code:
[StructLayout(LayoutKind.Sequential)]
public struct ST_EACH_CAMERA_INFO
{
[MarshalAs(UnmanagedType.LPStr)]
public string szCamName;
public ushort wWidth;
public ushort wHeight;
public Byte byFramerate;
public Byte bySchedule;
public Byte byQuality;
public Byte byAudio;
public Byte byVideoStandard;
public Byte byCovert;
public Byte byPTZ;
public Byte byVideoLoss;
public IntPtr nAlarmIn;
public IntPtr nAlarmOut;
}
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rich Cook
0100 1101 0110 1001 0110 0011 0110 1000 0110 0001 0110 0101 0110 1100 0010 0000 0100 0101 0110 1100 0110 1100 0110 0101 0111 0010
-
December 9th, 2013, 07:07 AM
#10
Re: C++ callback to C#
Originally Posted by HairyMonkeyMan
try defining your struct as follows:
Code:
[StructLayout(LayoutKind.Sequential)]
public struct ST_EACH_CAMERA_INFO
{
[MarshalAs(UnmanagedType.LPStr)]
public string szCamName;
public ushort wWidth;
public ushort wHeight;
public Byte byFramerate;
public Byte bySchedule;
public Byte byQuality;
public Byte byAudio;
public Byte byVideoStandard;
public Byte byCovert;
public Byte byPTZ;
public Byte byVideoLoss;
public IntPtr nAlarmIn;
public IntPtr nAlarmOut;
}
The szCamName now is right.
But the other values are wrongs again.
The documentation is the following:
ST_EACH_CAMERA_INFO
This data type contains information relevant to a camera.
typedef struct _tagEachCameraInfo
{
CHAR szCamName[32];
WORD wWidth;
WORD wHeight;
BYTE byFramerate;
BYTE bySchedule;
BYTE byQuality;
BYTE byAudio;
BYTE byVideoStandard;
BYTE byCovert;
BYTE byPTZ;
BYTE byVideoLoss;
INT nAlarmIn;
INT nAlarmOut; }ST_EACH_CAMERA_INFO,FAR *LPST_EACH_CAMERA_INFO;
szCamName: The camera's name.
wWidth: The width of camera's video.
wHeight: The height of camera's video.
byFramerate: The speed of the camera's video.
bySchedule: The camera's video schedule, specifically when the camera will begin recording video. The following are valid values:
•0 for No Recording
•1 for Normal
•2 for Motion
•3 for Alarm Input
•4 for Event
•5 for Data byQuality: The camera's video's image quality.
•0 for Lowest
•1 for Low
•2 for Normal
•3 for High
•4 for Best byAudio: The camera's audio mapping.
•0 for No Use
•1 - 8 for a specific audio channel byVideoStandard: The tv video standard/format being used.
•0 for NTSC
•1 for PAL byCovert: video coversion??
•0 for disabled
•1 for enabled byPTZ: pan, tilt, zoom
•0 for disabled
•1 for enabled byVideoLoss: video loss detection
•0 for disabled
•1 for enabled nAlarmIn: The number of alarm inputs.
nAlarmOut: The number of alarm outputs.
-
December 9th, 2013, 07:09 AM
#11
Re: C++ callback to C#
I'll not be online for a while, but have a look at the following (its not complete, but should be able to help)
http://msdn.microsoft.com/en-us/libr...(v=vs.90).aspx
Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning. - Rich Cook
0100 1101 0110 1001 0110 0011 0110 1000 0110 0001 0110 0101 0110 1100 0010 0000 0100 0101 0110 1100 0110 1100 0110 0101 0111 0010
-
December 9th, 2013, 04:32 PM
#12
Re: C++ callback to C#
Originally Posted by HairyMonkeyMan
Thanks a lot...it helps me!
I've another question about this callback.
I discovered from documentation that the second param of the DVR_OnCameraCallback must be an array of ST_EACH_CAMERA_INFO:
Code:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void DVR_OnCameraCallback(UIntPtr hServer, ST_EACH_CAMERA_INFO lpstEachCameraInfo);
How can I modify the above delegate in order to let it works correctly?
I think that there are 2 solutions: one is to passing directly an array of ST_EACH_CAMERA_INFO to the delegate, otherwise the second is to passing an IntPtr and then convert it into a ST_EACH_CAMERA_INFO array.
Please could someone suggest me the right way to let a callback returns an array of struct?
Thanks!
Marco
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
|