473,383 Members | 1,843 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,383 software developers and data experts.

Please Help - P/Invoke and unmanaged types

Don
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
Nov 16 '05 #1
8 2723
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

Nov 16 '05 #2
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

Nov 16 '05 #3
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

Nov 16 '05 #4
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

Nov 16 '05 #5
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

Nov 16 '05 #6
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
Nov 16 '05 #7
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

Nov 16 '05 #8
Don
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
Nov 16 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
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...
3
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...
1
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 ...
1
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...
2
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...
4
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...
5
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
5
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...
4
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...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
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 using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.