I have a third party C++ DLL that I am trying to use from C#. The
specific function I am trying to use is declared in C++ as follows:
ladybugConvertToMultipleBGRU32(
LadybugContext context,
const LadybugImage* pimage,
unsigned char* arpszDestBuffers[ LADYBUG_NUM_CAMERAS ],
LadybugImageInfo* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):
unsigned char* arpTextureBuffers[ LADYBUG_NUM_CAMERAS ];
for(i = 0; i<LADYBUG_NUM_CAMERAS;i++)
{
arpTextureBuffers[i] =
new unsigned char[LADYBUG_RAW_IMAGE_COLS * LADYBUG_RAW_IMAGE_ROWS *
4];
}
error = ladybugConvertToMultipleBGRU32(
ladybug,
&image,
&arpTextureBuffers[0],
NULL);
I have tried (unsuccessfully, for the past two days) many combinations
of DllImport function declarations and ways of constructing the item
to pass in the third parameter (&arpTextureBuffers[0]). I have seen a
zillion posts, but none have been close enough to help me. How do I
construct the DllImport function, and how to I create the appropriate
item to pass to the third parameter? Any help would be greatly
appreciated.
Thanks in advance,
Don 8 2726
Hi,
Thanks for your reply. I am still having some trouble, probably with
the 2nd parameter (LadybugImage* pimage). I declared the LadyBugImage
struct as a class in my C# code as follows:
[StructLayout(LayoutKind.Sequential)]
unsafe public class LadybugImage{
public UInt32 uiCols = 0;
public UInt32 uiRows = 0;
public LadybugVideoMode videoMode = new LadybugVideoMode();
public LadybugTimestamp timestamp = new LadybugTimestamp();
public LadybugImageInfo imageInfo = new LadybugImageInfo();
// public string pData = "";
unsafe public byte* pData;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public UInt32[] ulReserved;
}
I suspect that the member pData is causing me grief, and/or the fact
that I used class instead of struct. Any suggestions here? If it
weren't for the complex structures, I think this would be pretty easy.
I couldn't help but notice that you substituted a 6 for LB_NUM_CAMERAS
when declaring pBuffer. Are you familiar with the LadyBug API? If so
are you using it w/ .NET?
Thanks again,
Don
"BMermuys" <so*****@someone.com> wrote in message news:<ud**************@TK2MSFTNGP09.phx.gbl>... Hi,
You can't have a managed type that you can pass as such.
1. You can use a managed type and an unmanaged buffer and copy between them after and/or before the function call.
* managed buffer: byte [][] mBuffer = new byte[LB_NUM_CAMERAS][]; for (int i=0; i<LB_NUM_CAMERAS; ++i) mBuffer[i] = new byte[ LB_COLS * LB_ROWS * 4 ];
* unmanaged buffer: IntPtr [] pBuffer = new IntPtr[6]; for (int i=0; i<LB_NUM_CAMERAS; ++i) pBuffer[i] = Marshal.AllocHGlobal( LB_COLS * LB_ROWS * 4 );
* copy managed to unmanaged (eg before function call) for (int i=0; i<LB_NUM_CAMERAS; ++i) Marshal.Copy ( mBuffer[i], 0, pBuffer[i], LB_COLS * LB_ROWS * 4 );
* copy unmanaged to managed (eg after function call) for (int i=0; i<LB_NUM_CAMERAS; ++i) Marshal.Copy ( pBuffer[i], mBuffer[i], 0, LB_COLS * LB_ROWS * 4 );
* unmanaged function :
[DllImport(....) ] ladybugConvertToMultipleBGRU32( ..., ... , IntPtr [] p, ... );
pBuffer is an IntPtr[] so pass it as the 3th parameter.
* cleanup unmanaged memory for (int i= 0; i<LB_NUM_CAMERAS; ++i ) Marshal.FreeHGlobal ( pBuffer[i] );
2. _OR_ you can only use an unmanaged buffer and manipulate this with properties or methods. This way you avoid copying. (You could put this in a class and make sure there is access to pBuffer so you can call the unmanaged function)
* unmanaged buffer: IntPtr [] pBuffer = new IntPtr[6]; for (int i=0; i<LB_NUM_CAMERAS; ++i) pBuffer[i] = Marshal.AllocHGlobal( LB_COLS * LB_ROWS * 4 );
* read data public byte ReadData( int camera, int idx ) { // TODO check if idx < rows*cols*4 return Marshal.ReadByte ( pBuffer[camera], idx ); }
* write data public void WriteData( int camera, int idx, byte value ) { // TODO check if idx < rows*cols*4 Marshal.WriteByte ( pBuffer[camera], idx, value ); } HTH, greetings
"Don" <ka**@wsdot.wa.gov> wrote in message news:13**************************@posting.google.c om... I have a third party C++ DLL that I am trying to use from C#. The specific function I am trying to use is declared in C++ as follows:
ladybugConvertToMultipleBGRU32( LadybugContext context, const LadybugImage* pimage, unsigned char* arpszDestBuffers[ LADYBUG_NUM_CAMERAS ], LadybugImageInfo* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):
unsigned char* arpTextureBuffers[ LADYBUG_NUM_CAMERAS ]; for(i = 0; i<LADYBUG_NUM_CAMERAS;i++) { arpTextureBuffers[i] = new unsigned char[LADYBUG_RAW_IMAGE_COLS * LADYBUG_RAW_IMAGE_ROWS * 4]; }
error = ladybugConvertToMultipleBGRU32( ladybug, &image, &arpTextureBuffers[0], NULL);
I have tried (unsuccessfully, for the past two days) many combinations of DllImport function declarations and ways of constructing the item to pass in the third parameter (&arpTextureBuffers[0]). I have seen a zillion posts, but none have been close enough to help me. How do I construct the DllImport function, and how to I create the appropriate item to pass to the third parameter? Any help would be greatly appreciated.
Thanks in advance, Don
Hi,
"Don" <ka**@wsdot.wa.gov> wrote in message
news:13**************************@posting.google.c om... Hi,
Thanks for your reply. I am still having some trouble, probably with the 2nd parameter (LadybugImage* pimage). I declared the LadyBugImage struct as a class in my C# code as follows:
[StructLayout(LayoutKind.Sequential)] unsafe public class LadybugImage{ public UInt32 uiCols = 0; public UInt32 uiRows = 0; public LadybugVideoMode videoMode = new LadybugVideoMode(); public LadybugTimestamp timestamp = new LadybugTimestamp(); public LadybugImageInfo imageInfo = new LadybugImageInfo(); // public string pData = ""; unsafe public byte* pData; [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)] public UInt32[] ulReserved; }
I suspect that the member pData is causing me grief, and/or the fact that I used class instead of struct. Any suggestions here? If it
I can only say that if the parameter is LadybugImage* then you can use a
class or a struct as ref parameter). Both are valid.
weren't for the complex structures, I think this would be pretty easy.
I couldn't help but notice that you substituted a 6 for LB_NUM_CAMERAS when declaring pBuffer. Are you familiar with the LadyBug API? If so
Not at all. I just read your previous post. I did check the internet, found
the ladybug but no public information about the sdk.
If you want more help you should post all c structs (concerning the
function). Also some information about what pData suppose to do. Do you
need to fill it, does the dll fill it or does the dll just set a pointer to
allocated data.
Maybe some c code that demonstrates the complete use of the function, etc...
hth,
greetings
are you using it w/ .NET?
Thanks again, Don
"BMermuys" <so*****@someone.com> wrote in message
news:<ud**************@TK2MSFTNGP09.phx.gbl>... Hi,
You can't have a managed type that you can pass as such.
1. You can use a managed type and an unmanaged buffer and copy between
them after and/or before the function call.
* managed buffer: byte [][] mBuffer = new byte[LB_NUM_CAMERAS][]; for (int i=0; i<LB_NUM_CAMERAS; ++i) mBuffer[i] = new byte[ LB_COLS * LB_ROWS * 4 ];
* unmanaged buffer: IntPtr [] pBuffer = new IntPtr[6]; for (int i=0; i<LB_NUM_CAMERAS; ++i) pBuffer[i] = Marshal.AllocHGlobal( LB_COLS * LB_ROWS * 4 );
* copy managed to unmanaged (eg before function call) for (int i=0; i<LB_NUM_CAMERAS; ++i) Marshal.Copy ( mBuffer[i], 0, pBuffer[i], LB_COLS * LB_ROWS * 4 );
* copy unmanaged to managed (eg after function call) for (int i=0; i<LB_NUM_CAMERAS; ++i) Marshal.Copy ( pBuffer[i], mBuffer[i], 0, LB_COLS * LB_ROWS * 4 );
* unmanaged function :
[DllImport(....) ] ladybugConvertToMultipleBGRU32( ..., ... , IntPtr [] p, ... );
pBuffer is an IntPtr[] so pass it as the 3th parameter.
* cleanup unmanaged memory for (int i= 0; i<LB_NUM_CAMERAS; ++i ) Marshal.FreeHGlobal ( pBuffer[i] );
2. _OR_ you can only use an unmanaged buffer and manipulate this with properties or methods. This way you avoid copying. (You could put this
in a class and make sure there is access to pBuffer so you can call the unmanaged function)
* unmanaged buffer: IntPtr [] pBuffer = new IntPtr[6]; for (int i=0; i<LB_NUM_CAMERAS; ++i) pBuffer[i] = Marshal.AllocHGlobal( LB_COLS * LB_ROWS * 4 );
* read data public byte ReadData( int camera, int idx ) { // TODO check if idx < rows*cols*4 return Marshal.ReadByte ( pBuffer[camera], idx ); }
* write data public void WriteData( int camera, int idx, byte value ) { // TODO check if idx < rows*cols*4 Marshal.WriteByte ( pBuffer[camera], idx, value ); } HTH, greetings
"Don" <ka**@wsdot.wa.gov> wrote in message news:13**************************@posting.google.c om... I have a third party C++ DLL that I am trying to use from C#. The specific function I am trying to use is declared in C++ as follows:
ladybugConvertToMultipleBGRU32( LadybugContext context, const LadybugImage* pimage, unsigned char* arpszDestBuffers[ LADYBUG_NUM_CAMERAS ], LadybugImageInfo* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):
unsigned char* arpTextureBuffers[ LADYBUG_NUM_CAMERAS ]; for(i = 0; i<LADYBUG_NUM_CAMERAS;i++) { arpTextureBuffers[i] = new unsigned char[LADYBUG_RAW_IMAGE_COLS * LADYBUG_RAW_IMAGE_ROWS * 4]; }
error = ladybugConvertToMultipleBGRU32( ladybug, &image, &arpTextureBuffers[0], NULL);
I have tried (unsuccessfully, for the past two days) many combinations of DllImport function declarations and ways of constructing the item to pass in the third parameter (&arpTextureBuffers[0]). I have seen a zillion posts, but none have been close enough to help me. How do I construct the DllImport function, and how to I create the appropriate item to pass to the third parameter? Any help would be greatly appreciated.
Thanks in advance, Don
Hi,
You can't have a managed type that you can pass as such.
1. You can use a managed type and an unmanaged buffer and copy between them
after and/or before the function call.
* managed buffer:
byte [][] mBuffer = new byte[LB_NUM_CAMERAS][];
for (int i=0; i<LB_NUM_CAMERAS; ++i)
mBuffer[i] = new byte[ LB_COLS * LB_ROWS * 4 ];
* unmanaged buffer:
IntPtr [] pBuffer = new IntPtr[6];
for (int i=0; i<LB_NUM_CAMERAS; ++i)
pBuffer[i] = Marshal.AllocHGlobal( LB_COLS * LB_ROWS * 4 );
* copy managed to unmanaged (eg before function call)
for (int i=0; i<LB_NUM_CAMERAS; ++i)
Marshal.Copy ( mBuffer[i], 0, pBuffer[i], LB_COLS * LB_ROWS * 4 );
* copy unmanaged to managed (eg after function call)
for (int i=0; i<LB_NUM_CAMERAS; ++i)
Marshal.Copy ( pBuffer[i], mBuffer[i], 0, LB_COLS * LB_ROWS * 4 );
* unmanaged function :
[DllImport(....) ]
ladybugConvertToMultipleBGRU32( ..., ... , IntPtr [] p, ... );
pBuffer is an IntPtr[] so pass it as the 3th parameter.
* cleanup unmanaged memory
for (int i= 0; i<LB_NUM_CAMERAS; ++i )
Marshal.FreeHGlobal ( pBuffer[i] );
2. _OR_ you can only use an unmanaged buffer and manipulate this with
properties or methods. This way you avoid copying. (You could put this in
a class and make sure there is access to pBuffer so you can call the
unmanaged function)
* unmanaged buffer:
IntPtr [] pBuffer = new IntPtr[6];
for (int i=0; i<LB_NUM_CAMERAS; ++i)
pBuffer[i] = Marshal.AllocHGlobal( LB_COLS * LB_ROWS * 4 );
* read data
public byte ReadData( int camera, int idx )
{
// TODO check if idx < rows*cols*4
return Marshal.ReadByte ( pBuffer[camera], idx );
}
* write data
public void WriteData( int camera, int idx, byte value )
{
// TODO check if idx < rows*cols*4
Marshal.WriteByte ( pBuffer[camera], idx, value );
}
HTH,
greetings
"Don" <ka**@wsdot.wa.gov> wrote in message
news:13**************************@posting.google.c om... I have a third party C++ DLL that I am trying to use from C#. The specific function I am trying to use is declared in C++ as follows:
ladybugConvertToMultipleBGRU32( LadybugContext context, const LadybugImage* pimage, unsigned char* arpszDestBuffers[ LADYBUG_NUM_CAMERAS ], LadybugImageInfo* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):
unsigned char* arpTextureBuffers[ LADYBUG_NUM_CAMERAS ]; for(i = 0; i<LADYBUG_NUM_CAMERAS;i++) { arpTextureBuffers[i] = new unsigned char[LADYBUG_RAW_IMAGE_COLS * LADYBUG_RAW_IMAGE_ROWS * 4]; }
error = ladybugConvertToMultipleBGRU32( ladybug, &image, &arpTextureBuffers[0], NULL);
I have tried (unsuccessfully, for the past two days) many combinations of DllImport function declarations and ways of constructing the item to pass in the third parameter (&arpTextureBuffers[0]). I have seen a zillion posts, but none have been close enough to help me. How do I construct the DllImport function, and how to I create the appropriate item to pass to the third parameter? Any help would be greatly appreciated.
Thanks in advance, Don
Hi,
Thanks for your reply. I am still having some trouble, probably with
the 2nd parameter (LadybugImage* pimage). I declared the LadyBugImage
struct as a class in my C# code as follows:
[StructLayout(LayoutKind.Sequential)]
unsafe public class LadybugImage{
public UInt32 uiCols = 0;
public UInt32 uiRows = 0;
public LadybugVideoMode videoMode = new LadybugVideoMode();
public LadybugTimestamp timestamp = new LadybugTimestamp();
public LadybugImageInfo imageInfo = new LadybugImageInfo();
// public string pData = "";
unsafe public byte* pData;
[MarshalAs(UnmanagedType.ByValArray, SizeConst=4)]
public UInt32[] ulReserved;
}
I suspect that the member pData is causing me grief, and/or the fact
that I used class instead of struct. Any suggestions here? If it
weren't for the complex structures, I think this would be pretty easy.
I couldn't help but notice that you substituted a 6 for LB_NUM_CAMERAS
when declaring pBuffer. Are you familiar with the LadyBug API? If so
are you using it w/ .NET?
Thanks again,
Don
"BMermuys" <so*****@someone.com> wrote in message news:<ud**************@TK2MSFTNGP09.phx.gbl>... Hi,
You can't have a managed type that you can pass as such.
1. You can use a managed type and an unmanaged buffer and copy between them after and/or before the function call.
* managed buffer: byte [][] mBuffer = new byte[LB_NUM_CAMERAS][]; for (int i=0; i<LB_NUM_CAMERAS; ++i) mBuffer[i] = new byte[ LB_COLS * LB_ROWS * 4 ];
* unmanaged buffer: IntPtr [] pBuffer = new IntPtr[6]; for (int i=0; i<LB_NUM_CAMERAS; ++i) pBuffer[i] = Marshal.AllocHGlobal( LB_COLS * LB_ROWS * 4 );
* copy managed to unmanaged (eg before function call) for (int i=0; i<LB_NUM_CAMERAS; ++i) Marshal.Copy ( mBuffer[i], 0, pBuffer[i], LB_COLS * LB_ROWS * 4 );
* copy unmanaged to managed (eg after function call) for (int i=0; i<LB_NUM_CAMERAS; ++i) Marshal.Copy ( pBuffer[i], mBuffer[i], 0, LB_COLS * LB_ROWS * 4 );
* unmanaged function :
[DllImport(....) ] ladybugConvertToMultipleBGRU32( ..., ... , IntPtr [] p, ... );
pBuffer is an IntPtr[] so pass it as the 3th parameter.
* cleanup unmanaged memory for (int i= 0; i<LB_NUM_CAMERAS; ++i ) Marshal.FreeHGlobal ( pBuffer[i] );
2. _OR_ you can only use an unmanaged buffer and manipulate this with properties or methods. This way you avoid copying. (You could put this in a class and make sure there is access to pBuffer so you can call the unmanaged function)
* unmanaged buffer: IntPtr [] pBuffer = new IntPtr[6]; for (int i=0; i<LB_NUM_CAMERAS; ++i) pBuffer[i] = Marshal.AllocHGlobal( LB_COLS * LB_ROWS * 4 );
* read data public byte ReadData( int camera, int idx ) { // TODO check if idx < rows*cols*4 return Marshal.ReadByte ( pBuffer[camera], idx ); }
* write data public void WriteData( int camera, int idx, byte value ) { // TODO check if idx < rows*cols*4 Marshal.WriteByte ( pBuffer[camera], idx, value ); } HTH, greetings
"Don" <ka**@wsdot.wa.gov> wrote in message news:13**************************@posting.google.c om... I have a third party C++ DLL that I am trying to use from C#. The specific function I am trying to use is declared in C++ as follows:
ladybugConvertToMultipleBGRU32( LadybugContext context, const LadybugImage* pimage, unsigned char* arpszDestBuffers[ LADYBUG_NUM_CAMERAS ], LadybugImageInfo* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):
unsigned char* arpTextureBuffers[ LADYBUG_NUM_CAMERAS ]; for(i = 0; i<LADYBUG_NUM_CAMERAS;i++) { arpTextureBuffers[i] = new unsigned char[LADYBUG_RAW_IMAGE_COLS * LADYBUG_RAW_IMAGE_ROWS * 4]; }
error = ladybugConvertToMultipleBGRU32( ladybug, &image, &arpTextureBuffers[0], NULL);
I have tried (unsuccessfully, for the past two days) many combinations of DllImport function declarations and ways of constructing the item to pass in the third parameter (&arpTextureBuffers[0]). I have seen a zillion posts, but none have been close enough to help me. How do I construct the DllImport function, and how to I create the appropriate item to pass to the third parameter? Any help would be greatly appreciated.
Thanks in advance, Don
Hi,
"Don" <ka**@wsdot.wa.gov> wrote in message
news:13**************************@posting.google.c om... Hi,
Thanks for your reply. I am still having some trouble, probably with the 2nd parameter (LadybugImage* pimage). I declared the LadyBugImage struct as a class in my C# code as follows:
[StructLayout(LayoutKind.Sequential)] unsafe public class LadybugImage{ public UInt32 uiCols = 0; public UInt32 uiRows = 0; public LadybugVideoMode videoMode = new LadybugVideoMode(); public LadybugTimestamp timestamp = new LadybugTimestamp(); public LadybugImageInfo imageInfo = new LadybugImageInfo(); // public string pData = ""; unsafe public byte* pData; [MarshalAs(UnmanagedType.ByValArray, SizeConst=4)] public UInt32[] ulReserved; }
I suspect that the member pData is causing me grief, and/or the fact that I used class instead of struct. Any suggestions here? If it
I can only say that if the parameter is LadybugImage* then you can use a
class or a struct as ref parameter). Both are valid.
weren't for the complex structures, I think this would be pretty easy.
I couldn't help but notice that you substituted a 6 for LB_NUM_CAMERAS when declaring pBuffer. Are you familiar with the LadyBug API? If so
Not at all. I just read your previous post. I did check the internet, found
the ladybug but no public information about the sdk.
If you want more help you should post all c structs (concerning the
function). Also some information about what pData suppose to do. Do you
need to fill it, does the dll fill it or does the dll just set a pointer to
allocated data.
Maybe some c code that demonstrates the complete use of the function, etc...
hth,
greetings
are you using it w/ .NET?
Thanks again, Don
"BMermuys" <so*****@someone.com> wrote in message
news:<ud**************@TK2MSFTNGP09.phx.gbl>... Hi,
You can't have a managed type that you can pass as such.
1. You can use a managed type and an unmanaged buffer and copy between
them after and/or before the function call.
* managed buffer: byte [][] mBuffer = new byte[LB_NUM_CAMERAS][]; for (int i=0; i<LB_NUM_CAMERAS; ++i) mBuffer[i] = new byte[ LB_COLS * LB_ROWS * 4 ];
* unmanaged buffer: IntPtr [] pBuffer = new IntPtr[6]; for (int i=0; i<LB_NUM_CAMERAS; ++i) pBuffer[i] = Marshal.AllocHGlobal( LB_COLS * LB_ROWS * 4 );
* copy managed to unmanaged (eg before function call) for (int i=0; i<LB_NUM_CAMERAS; ++i) Marshal.Copy ( mBuffer[i], 0, pBuffer[i], LB_COLS * LB_ROWS * 4 );
* copy unmanaged to managed (eg after function call) for (int i=0; i<LB_NUM_CAMERAS; ++i) Marshal.Copy ( pBuffer[i], mBuffer[i], 0, LB_COLS * LB_ROWS * 4 );
* unmanaged function :
[DllImport(....) ] ladybugConvertToMultipleBGRU32( ..., ... , IntPtr [] p, ... );
pBuffer is an IntPtr[] so pass it as the 3th parameter.
* cleanup unmanaged memory for (int i= 0; i<LB_NUM_CAMERAS; ++i ) Marshal.FreeHGlobal ( pBuffer[i] );
2. _OR_ you can only use an unmanaged buffer and manipulate this with properties or methods. This way you avoid copying. (You could put this
in a class and make sure there is access to pBuffer so you can call the unmanaged function)
* unmanaged buffer: IntPtr [] pBuffer = new IntPtr[6]; for (int i=0; i<LB_NUM_CAMERAS; ++i) pBuffer[i] = Marshal.AllocHGlobal( LB_COLS * LB_ROWS * 4 );
* read data public byte ReadData( int camera, int idx ) { // TODO check if idx < rows*cols*4 return Marshal.ReadByte ( pBuffer[camera], idx ); }
* write data public void WriteData( int camera, int idx, byte value ) { // TODO check if idx < rows*cols*4 Marshal.WriteByte ( pBuffer[camera], idx, value ); } HTH, greetings
"Don" <ka**@wsdot.wa.gov> wrote in message news:13**************************@posting.google.c om... I have a third party C++ DLL that I am trying to use from C#. The specific function I am trying to use is declared in C++ as follows:
ladybugConvertToMultipleBGRU32( LadybugContext context, const LadybugImage* pimage, unsigned char* arpszDestBuffers[ LADYBUG_NUM_CAMERAS ], LadybugImageInfo* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):
unsigned char* arpTextureBuffers[ LADYBUG_NUM_CAMERAS ]; for(i = 0; i<LADYBUG_NUM_CAMERAS;i++) { arpTextureBuffers[i] = new unsigned char[LADYBUG_RAW_IMAGE_COLS * LADYBUG_RAW_IMAGE_ROWS * 4]; }
error = ladybugConvertToMultipleBGRU32( ladybug, &image, &arpTextureBuffers[0], NULL);
I have tried (unsuccessfully, for the past two days) many combinations of DllImport function declarations and ways of constructing the item to pass in the third parameter (&arpTextureBuffers[0]). I have seen a zillion posts, but none have been close enough to help me. How do I construct the DllImport function, and how to I create the appropriate item to pass to the third parameter? Any help would be greatly appreciated.
Thanks in advance, Don
Hi again,
Thanks for the response. The relavent C++ typedefs are as follows:
typedef struct LadybugImage
{
/** Columns, in pixels, of a single image corresponding to the
current
video mode. */
unsigned int uiCols;
/** Rows, in pixels, of a single image corresponding to the current
video mode. */
unsigned int uiRows;
/** Video mode that this image was captured with. */
LadybugVideoMode videoMode;
/** Timestamp of this image. */
LadybugTimestamp timeStamp;
/** Image information for this image. */
LadybugImageInfo imageInfo;
/**
* Pointer to the actual image data. The data will be of length
* iRows * iCols * LADYBUG_NUM_CAMERAS. The format of this data
* is byte interleaved by camera and not useful for anything
besides
* feeding into one of the colour processing functions, or storage
* on disk for later processing.
*/
unsigned char* pData;
/** Reserved for future image information */
unsigned long ulReserved[ 4 ];
} LadybugImage;
/**
* The possible ladybug preview video modes. Modes other than
1024x768 do
* hardware downsampling to provide higher framerates. These do not
affect
* the size of the images saved to the HD.
*/
typedef enum LadybugVideoMode
{
/** 1024 x 768 x 6 cameras */
LADYBUG_VIDEOMODE_LADYBUG_1024x768x6,
/** 512 x 384 x 6 cameras */
LADYBUG_VIDEOMODE_LADYBUG_512x384x6,
/** 256 x 192 x 6 cameras */
LADYBUG_VIDEOMODE_LADYBUG_256x192x6,
/** 128 x 96 x 6 cameras */
LADYBUG_VIDEOMODE_LADYBUG_128x96x6,
/** Number of possible video modes. */
LADYBUG_NUM_VIDEOMODES,
/** Hook for "any usable video mode." */
LADYBUG_VIDEOMODE_ANY,
} LadybugVideoMode;
/**
* The timestamp structure for ladybug images. "Cycle time" in this
context
* is a low-level 1394 construct used for synchronizing cameras across
* multiple nodes.
*/
typedef struct LadybugTimestamp
{
/** The number of seconds since the epoch. */
unsigned long ulSeconds;
/** The microseconds component. */
unsigned long ulMicroSeconds;
/** The cycle time seconds. 0-127. */
unsigned long ulCycleSeconds;
/** The cycle time count. 0-7999. */
unsigned long ulCycleCount;
} LadybugTimestamp;
/**
* Out of band image information stored to the hard drive as part of
each
* image set at capture time.
*/
typedef struct LadybugImageInfo
{
/** Constant fingerprint, should be 0xCAFEBABE */
unsigned long ulFingerprint;
/** Structure version number, should be 0x00000002 */
unsigned long ulVersion;
/** Timestamp, in seconds, since the UNIX time epoch. */
unsigned long ulTimeSeconds;
/** Microsecond fraction of above second */
unsigned long ulTimeMicroSeconds;
/** Sequence number of the image. Reset to zero when the head
powers up
* and incremented for every image. */
unsigned long ulSequenceId;
/** Horizontal refresh rate. (reserved) */
unsigned long ulHRate;
/** Actual adjusted gains used by each of the 6 cameras. Similar
to the
* DCAM gain register. */
unsigned long arulGainAdjust[ 6 ];
/** A copy of the DCAM whitebalance register */
unsigned long ulWhiteBalance;
/** This is the same as register 0x1044, described in the PGR
Dragonfly
* Technical Reference Manual. */
unsigned long ulBayerGain;
/** This is the same as register 0x1040, described in the PGR
Dragonfly
* Technical Reference Manual. */
unsigned long ulBayerMap;
/** A copy of the Brightness DCAM register. */
unsigned long ulBrightness;
/** A copy of the Gamma DCAM register. */
unsigned long ulGamma;
/** The head unit serial number. */
unsigned long ulSerialNum;
/** Shutter values for each camera. Similar to the DCAM shutter
* register. */
unsigned long ulShutter[ 6 ];
/** Reserved for future out of band image values. */
unsigned long ulReserved[ 6 ];
} LadybugImageInfo;
The function I need to call follows:
/**
* Parse the 6 images in a LADYBUG_VIDEOMODE_LADYBUG LadybugImage into
* 6 BGRU32 buffers. Color processing will use the current color
processing
* method.
*
* @param context The LadybugContext to access.
* @param arpszDestBuffers An array of pointers to destination
buffers that
* will hold the processed images.
* @retval pImageInfo Image information extracted from the
retrieved
* image. Use NULL to disable.
*
* @return A LadybugError indicating the success of the function.
*
* @note BGRU32 images will only be produced for the camera units that
* are included in the processing camera bit mask
* (see ladybugSetProcessingCameras()).
* @note The alpha mask (see ladybuggeom.h) will only be written to
the
* destination buffer the first time any of the Convert
functions
* are called. If you wish to use a different destination
buffer,
* call ladybugSetAlphaMasking( true ) again.
*/
LADYBUGDLL_API LadybugError
ladybugConvertToMultipleBGRU32(
LadybugContext context,
const LadybugImage* pimage,
unsigned char* arpszDestBuffers[ LADYBUG_NUM_CAMERAS ],
LadybugImageInfo* pImageInfo );
Don't worry about LadybugContext. I am able to succesfully create and
destroy it via two other API calls. I feel pretty good about the
code you supplied for creating and copying back & forth to the
unmanaged buffer. I am thinking the way I declared the LadybugImage
struct is my problem (particularily the pData member). Any
suggestions would be greatly appreciated. Let me know if you need
more info.
Thanks again,
Don
Hi,
c# structs:
[StructLayout(LayoutKind.Sequential)]
public struct LadyBugTimestamp
{
uint Seconds;
uint MicroSeconds;
uint CycleSeconds;
uint CycleCount;
}
public enum LadybugVideoMode
{
LADYBUG_VIDEOMODE_LADYBUG_1024x768x6,
LADYBUG_VIDEOMODE_LADYBUG_512x384x6,
LADYBUG_VIDEOMODE_LADYBUG_256x192x6,
LADYBUG_VIDEOMODE_LADYBUG_128x96x6,
LADYBUG_NUM_VIDEOMODES,
LADYBUG_VIDEOMODE_ANY
}
[StructLayout(LayoutKind.Sequential)]
public struct LadybugImageInfo
{
public uint Fingerprint;
public uint Version;
public uint TimeSeconds;
public uint TimeMicroSeconds;
public uint SequenceId;
public uint HRate;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=6)]
public uint[] GainAdjust;
public uint WhiteBalance;
public uint BayerGain;
public uint BayerMap;
public uint Brightness;
public uint Gamma;
public uint SerialNum;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=6)]
public uint[] Shutter;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=6)]
public uint[] Reserverd;
public LadybugImageInfo(int unused)
{ // constructor
GainAdjust = new byte[6];
Shutter = new byte[6];
Reserverd = new byte[6];
}
}
[StructLayout(StructLayoutEnum.Sequential)]
public struct LadybugImage
{
public uint Cols;
public uint Rows;
public int videoMode; // cast VideModeEnums to int or parse from int
public LadybugTimeStamp timeStamp;
public LadybugImageInfo imageInfo;
public IntPtr pData;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=4)]
public uint[] Reserved;
public LadybugImage(int unused)
{ // constructor
timeStamp = new LadybugTimeStamp();
imageInfo = new LadybugImageInfo(0);
Reserverd = new byte[4];
}
}
[DllImport(...)]
public static extern int ladybugConvertToMultipleBGRU32(
LadybugContext context,
ref LadybugImage image,
IntPtr[] pDestBuffers,
ref LadybugImageInfo ImageInfo );
public void test()
{
LadybugImagInfo ImageInfo = new LadybugImageInfo(0);
LadybugImage Image = new LadybugImage(0); // (*)
// eg. GetImage ( ref Image );
// Allocate unmanaged memory for DestBuffers
IntPtr[] pDestBuffers = new IntPtr[6];
for (int i=0; i<6; ++i)
pDestBuffers[i] = Marshal.AllocHGlobal(rows*cols*4);
// Call unmanaged function
ladybugConvertToMultipleBGRU32( context, ref Image, pDestBuffers, ref
ImageInfo );
// Create managed buffer, copy pDestBuffers into it and cleanup
unmanaged buffer
byte [][] DestBuffers = new byte[6][];
for (int i=0; i<6; ++i)
{
DestBuffers[i] = new byte[rows*cols*4];
Marshal.Copy( pDestBuffers[i], DestBuffers[i], 0, rows*cols*4 );
Marshal.HFreeGlobal( pDestBuffers[i] );
}
// If you allocated memory for Image.pImage then cleanup
Marshal.HFreeGlobal( Image.pImage );
// result is in DestBuffers
}
You may want to rearrange it.
(*)
It's still not clear where the data comes from that you want in Image.pData
:
1. If you have a unmanaged function (eg. void GetImage (LadybugImage*
image) ) which fills an Image structure then there are 2 options:
a. the function allocates memory for pData, then you don't have to
allocate memory yourself and the dll should export a function that frees the
data it allocated (eg. FreeImage(...) )
b. the caller must allocate memory for pData before calling GetImage,
then you need to allocate memory yourself:
Image.pData = Marshal.AllocHGlobal( Image.Rows * Image.Cols * 6 );
2. If the imagedata comes from a managed type, you'll need to allocate
memory and use Marshal.Copy or Marshal.WriteByte to marshal the data.
If you don't want to use parameter ImageInfo* then you can declare it as an
IntPtr and pass IntPtr.Zero.
HTH,
Greetings
Hi again
It turns out the creators of the Ladybug API have built in a versioning scheme using macros in the C++ environment. They apparently did not build the API to be used from outside of C++. The method names are transformed during the compile process. I was calling a method called ladybugConvertToMultipleBGRU32, based on the documentation and what I found in the .h file. However, in the compiled dll that I am using, the method I want is ladybugConvertToMultipleBGRU32_1_1_1_1_1_1_2_2. Their versioning scheme accounts for changes to structs that are passed as parameters. Somehow (I don't fully understand it), when I made my call to the ladybugConvertToMultipleBGRU32 method, the API was able to tell that I was trying to call the original version of the method and that there is a newer version that I should be using instead. This resulted in a message box (probably a Win API call, since I didn't have any messagebox code) telling me that I am trying to use an old version and should recompile with a newer version
I just wanted to thank you for all of your help. The advice you gave for parameter #3 (IntPtr[] arpszDestBuffers): type to use; and allocating/copying between managed/unmanaged helped alot
Thanks again
Don This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Yoni Rabinovitch |
last post by:
Is it possible to invoke a C# delegate/event handler asynchronously,
from unmanaged C++ ?
I assume this requires a Managed C++ wrapper, which would call
BeginInvoke on the delegate ?
Is this...
|
by: Daniel Jin |
last post by:
I'm an absolute newb to P/Invoke, and got stuck on this little thing, what would be the correct P/Invoke syntax to import the following dll function
NTSTATUS TdiRegisterProvider
IN...
|
by: Don |
last post by:
I have a third party C++ DLL that I am trying to use from C#. The
specific function I am trying to use is declared in C++ as follows:
ladybugConvertToMultipleBGRU32(
LadybugContext ...
|
by: Fedor Buyakov |
last post by:
hello all
i have a specific question according hiding unmanaged (native) types
in metadata for assemblies generated by c++ with managed extensions. i
understand what these types are nedeed in...
|
by: Bob Rock |
last post by:
Hello,
in the last few days I've made my first few attempts at creating mixed
C++ managed-unmanaged assemblies and looking afterwards with ILDASM
at what is visible in those assemblies from a...
|
by: William F. Kinsley |
last post by:
My understanding is that when I re-compile a existing MFC application with
the /clr switch, that the code generated is managed(with some exceptions)
but that the data isn't, i.e. not garbage...
|
by: chenedor |
last post by:
Hi all
I am a bit confuse about unboxing... what is the difference and what
is best practice ?
object o = __box(1234);
int n = *dynamic_cast<__box int*>(o);
of
|
by: R. MacDonald |
last post by:
Hello, all,
I am currently working on a .Net (VB) application that invokes routines
in unmanaged (Fortran) DLLs. The unmanaged routines then communicate
with the .Net application by means of a...
|
by: Ian |
last post by:
I would like to hear from others who have considered and/or ported code from
traditional C++ to C++/CLI.
The class library I am considering porting to C++/CLI was written in
traditional C++ with...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Hystou |
last post by:
There are some requirements for setting up RAID:
1. The motherboard and BIOS support RAID configuration.
2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
|
by: agi2029 |
last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM).
In this session, we are pleased to welcome a new...
| |