473,801 Members | 2,400 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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:

ladybugConvertT oMultipleBGRU32 (
LadybugContext context,
const LadybugImage* pimage,
unsigned char* arpszDestBuffer s[ LADYBUG_NUM_CAM ERAS ],
LadybugImageInf o* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):

unsigned char* arpTextureBuffe rs[ LADYBUG_NUM_CAM ERAS ];
for(i = 0; i<LADYBUG_NUM_C AMERAS;i++)
{
arpTextureBuffe rs[i] =
new unsigned char[LADYBUG_RAW_IMA GE_COLS * LADYBUG_RAW_IMA GE_ROWS *
4];
}

error = ladybugConvertT oMultipleBGRU32 (
ladybug,
&image,
&arpTextureBuff ers[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 (&arpTextureBuf fers[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 2785
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(La youtKind.Sequen tial)]
unsafe public class LadybugImage{
public UInt32 uiCols = 0;
public UInt32 uiRows = 0;
public LadybugVideoMod e videoMode = new LadybugVideoMod e();
public LadybugTimestam p timestamp = new LadybugTimestam p();
public LadybugImageInf o imageInfo = new LadybugImageInf o();
// public string pData = "";
unsafe public byte* pData;
[MarshalAs(Unman agedType.ByValA rray, 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*****@someon e.com> wrote in message news:<ud******* *******@TK2MSFT NGP09.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_CAMERA S; ++i)
mBuffer[i] = new byte[ LB_COLS * LB_ROWS * 4 ];

* unmanaged buffer:
IntPtr [] pBuffer = new IntPtr[6];
for (int i=0; i<LB_NUM_CAMERA S; ++i)
pBuffer[i] = Marshal.AllocHG lobal( LB_COLS * LB_ROWS * 4 );

* copy managed to unmanaged (eg before function call)
for (int i=0; i<LB_NUM_CAMERA S; ++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_CAMERA S; ++i)
Marshal.Copy ( pBuffer[i], mBuffer[i], 0, LB_COLS * LB_ROWS * 4 );

* unmanaged function :

[DllImport(....) ]
ladybugConvertT oMultipleBGRU32 ( ..., ... , IntPtr [] p, ... );

pBuffer is an IntPtr[] so pass it as the 3th parameter.

* cleanup unmanaged memory
for (int i= 0; i<LB_NUM_CAMERA S; ++i )
Marshal.FreeHGl obal ( 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_CAMERA S; ++i)
pBuffer[i] = Marshal.AllocHG lobal( LB_COLS * LB_ROWS * 4 );

* read data
public byte ReadData( int camera, int idx )
{
// TODO check if idx < rows*cols*4
return Marshal.ReadByt e ( pBuffer[camera], idx );
}

* write data
public void WriteData( int camera, int idx, byte value )
{
// TODO check if idx < rows*cols*4
Marshal.WriteBy te ( pBuffer[camera], idx, value );
}

HTH,
greetings
"Don" <ka**@wsdot.wa. gov> wrote in message
news:13******** *************** ***@posting.goo gle.com...
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:

ladybugConvertT oMultipleBGRU32 (
LadybugContext context,
const LadybugImage* pimage,
unsigned char* arpszDestBuffer s[ LADYBUG_NUM_CAM ERAS ],
LadybugImageInf o* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):

unsigned char* arpTextureBuffe rs[ LADYBUG_NUM_CAM ERAS ];
for(i = 0; i<LADYBUG_NUM_C AMERAS;i++)
{
arpTextureBuffe rs[i] =
new unsigned char[LADYBUG_RAW_IMA GE_COLS * LADYBUG_RAW_IMA GE_ROWS *
4];
}

error = ladybugConvertT oMultipleBGRU32 (
ladybug,
&image,
&arpTextureBuff ers[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 (&arpTextureBuf fers[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.goo gle.com...
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(La youtKind.Sequen tial)]
unsafe public class LadybugImage{
public UInt32 uiCols = 0;
public UInt32 uiRows = 0;
public LadybugVideoMod e videoMode = new LadybugVideoMod e();
public LadybugTimestam p timestamp = new LadybugTimestam p();
public LadybugImageInf o imageInfo = new LadybugImageInf o();
// public string pData = "";
unsafe public byte* pData;
[MarshalAs(Unman agedType.ByValA rray, 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*****@someon e.com> wrote in message

news:<ud******* *******@TK2MSFT NGP09.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_CAMERA S; ++i)
mBuffer[i] = new byte[ LB_COLS * LB_ROWS * 4 ];

* unmanaged buffer:
IntPtr [] pBuffer = new IntPtr[6];
for (int i=0; i<LB_NUM_CAMERA S; ++i)
pBuffer[i] = Marshal.AllocHG lobal( LB_COLS * LB_ROWS * 4 );

* copy managed to unmanaged (eg before function call)
for (int i=0; i<LB_NUM_CAMERA S; ++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_CAMERA S; ++i)
Marshal.Copy ( pBuffer[i], mBuffer[i], 0, LB_COLS * LB_ROWS * 4 );

* unmanaged function :

[DllImport(....) ]
ladybugConvertT oMultipleBGRU32 ( ..., ... , IntPtr [] p, ... );

pBuffer is an IntPtr[] so pass it as the 3th parameter.

* cleanup unmanaged memory
for (int i= 0; i<LB_NUM_CAMERA S; ++i )
Marshal.FreeHGl obal ( 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_CAMERA S; ++i)
pBuffer[i] = Marshal.AllocHG lobal( LB_COLS * LB_ROWS * 4 );

* read data
public byte ReadData( int camera, int idx )
{
// TODO check if idx < rows*cols*4
return Marshal.ReadByt e ( pBuffer[camera], idx );
}

* write data
public void WriteData( int camera, int idx, byte value )
{
// TODO check if idx < rows*cols*4
Marshal.WriteBy te ( pBuffer[camera], idx, value );
}

HTH,
greetings
"Don" <ka**@wsdot.wa. gov> wrote in message
news:13******** *************** ***@posting.goo gle.com...
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:

ladybugConvertT oMultipleBGRU32 (
LadybugContext context,
const LadybugImage* pimage,
unsigned char* arpszDestBuffer s[ LADYBUG_NUM_CAM ERAS ],
LadybugImageInf o* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):

unsigned char* arpTextureBuffe rs[ LADYBUG_NUM_CAM ERAS ];
for(i = 0; i<LADYBUG_NUM_C AMERAS;i++)
{
arpTextureBuffe rs[i] =
new unsigned char[LADYBUG_RAW_IMA GE_COLS * LADYBUG_RAW_IMA GE_ROWS *
4];
}

error = ladybugConvertT oMultipleBGRU32 (
ladybug,
&image,
&arpTextureBuff ers[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 (&arpTextureBuf fers[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_CAMERA S; ++i)
mBuffer[i] = new byte[ LB_COLS * LB_ROWS * 4 ];

* unmanaged buffer:
IntPtr [] pBuffer = new IntPtr[6];
for (int i=0; i<LB_NUM_CAMERA S; ++i)
pBuffer[i] = Marshal.AllocHG lobal( LB_COLS * LB_ROWS * 4 );

* copy managed to unmanaged (eg before function call)
for (int i=0; i<LB_NUM_CAMERA S; ++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_CAMERA S; ++i)
Marshal.Copy ( pBuffer[i], mBuffer[i], 0, LB_COLS * LB_ROWS * 4 );

* unmanaged function :

[DllImport(....) ]
ladybugConvertT oMultipleBGRU32 ( ..., ... , IntPtr [] p, ... );

pBuffer is an IntPtr[] so pass it as the 3th parameter.

* cleanup unmanaged memory
for (int i= 0; i<LB_NUM_CAMERA S; ++i )
Marshal.FreeHGl obal ( 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_CAMERA S; ++i)
pBuffer[i] = Marshal.AllocHG lobal( LB_COLS * LB_ROWS * 4 );

* read data
public byte ReadData( int camera, int idx )
{
// TODO check if idx < rows*cols*4
return Marshal.ReadByt e ( pBuffer[camera], idx );
}

* write data
public void WriteData( int camera, int idx, byte value )
{
// TODO check if idx < rows*cols*4
Marshal.WriteBy te ( pBuffer[camera], idx, value );
}

HTH,
greetings
"Don" <ka**@wsdot.wa. gov> wrote in message
news:13******** *************** ***@posting.goo gle.com...
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:

ladybugConvertT oMultipleBGRU32 (
LadybugContext context,
const LadybugImage* pimage,
unsigned char* arpszDestBuffer s[ LADYBUG_NUM_CAM ERAS ],
LadybugImageInf o* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):

unsigned char* arpTextureBuffe rs[ LADYBUG_NUM_CAM ERAS ];
for(i = 0; i<LADYBUG_NUM_C AMERAS;i++)
{
arpTextureBuffe rs[i] =
new unsigned char[LADYBUG_RAW_IMA GE_COLS * LADYBUG_RAW_IMA GE_ROWS *
4];
}

error = ladybugConvertT oMultipleBGRU32 (
ladybug,
&image,
&arpTextureBuff ers[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 (&arpTextureBuf fers[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(La youtKind.Sequen tial)]
unsafe public class LadybugImage{
public UInt32 uiCols = 0;
public UInt32 uiRows = 0;
public LadybugVideoMod e videoMode = new LadybugVideoMod e();
public LadybugTimestam p timestamp = new LadybugTimestam p();
public LadybugImageInf o imageInfo = new LadybugImageInf o();
// public string pData = "";
unsafe public byte* pData;
[MarshalAs(Unman agedType.ByValA rray, 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*****@someon e.com> wrote in message news:<ud******* *******@TK2MSFT NGP09.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_CAMERA S; ++i)
mBuffer[i] = new byte[ LB_COLS * LB_ROWS * 4 ];

* unmanaged buffer:
IntPtr [] pBuffer = new IntPtr[6];
for (int i=0; i<LB_NUM_CAMERA S; ++i)
pBuffer[i] = Marshal.AllocHG lobal( LB_COLS * LB_ROWS * 4 );

* copy managed to unmanaged (eg before function call)
for (int i=0; i<LB_NUM_CAMERA S; ++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_CAMERA S; ++i)
Marshal.Copy ( pBuffer[i], mBuffer[i], 0, LB_COLS * LB_ROWS * 4 );

* unmanaged function :

[DllImport(....) ]
ladybugConvertT oMultipleBGRU32 ( ..., ... , IntPtr [] p, ... );

pBuffer is an IntPtr[] so pass it as the 3th parameter.

* cleanup unmanaged memory
for (int i= 0; i<LB_NUM_CAMERA S; ++i )
Marshal.FreeHGl obal ( 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_CAMERA S; ++i)
pBuffer[i] = Marshal.AllocHG lobal( LB_COLS * LB_ROWS * 4 );

* read data
public byte ReadData( int camera, int idx )
{
// TODO check if idx < rows*cols*4
return Marshal.ReadByt e ( pBuffer[camera], idx );
}

* write data
public void WriteData( int camera, int idx, byte value )
{
// TODO check if idx < rows*cols*4
Marshal.WriteBy te ( pBuffer[camera], idx, value );
}

HTH,
greetings
"Don" <ka**@wsdot.wa. gov> wrote in message
news:13******** *************** ***@posting.goo gle.com...
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:

ladybugConvertT oMultipleBGRU32 (
LadybugContext context,
const LadybugImage* pimage,
unsigned char* arpszDestBuffer s[ LADYBUG_NUM_CAM ERAS ],
LadybugImageInf o* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):

unsigned char* arpTextureBuffe rs[ LADYBUG_NUM_CAM ERAS ];
for(i = 0; i<LADYBUG_NUM_C AMERAS;i++)
{
arpTextureBuffe rs[i] =
new unsigned char[LADYBUG_RAW_IMA GE_COLS * LADYBUG_RAW_IMA GE_ROWS *
4];
}

error = ladybugConvertT oMultipleBGRU32 (
ladybug,
&image,
&arpTextureBuff ers[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 (&arpTextureBuf fers[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.goo gle.com...
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(La youtKind.Sequen tial)]
unsafe public class LadybugImage{
public UInt32 uiCols = 0;
public UInt32 uiRows = 0;
public LadybugVideoMod e videoMode = new LadybugVideoMod e();
public LadybugTimestam p timestamp = new LadybugTimestam p();
public LadybugImageInf o imageInfo = new LadybugImageInf o();
// public string pData = "";
unsafe public byte* pData;
[MarshalAs(Unman agedType.ByValA rray, 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*****@someon e.com> wrote in message

news:<ud******* *******@TK2MSFT NGP09.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_CAMERA S; ++i)
mBuffer[i] = new byte[ LB_COLS * LB_ROWS * 4 ];

* unmanaged buffer:
IntPtr [] pBuffer = new IntPtr[6];
for (int i=0; i<LB_NUM_CAMERA S; ++i)
pBuffer[i] = Marshal.AllocHG lobal( LB_COLS * LB_ROWS * 4 );

* copy managed to unmanaged (eg before function call)
for (int i=0; i<LB_NUM_CAMERA S; ++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_CAMERA S; ++i)
Marshal.Copy ( pBuffer[i], mBuffer[i], 0, LB_COLS * LB_ROWS * 4 );

* unmanaged function :

[DllImport(....) ]
ladybugConvertT oMultipleBGRU32 ( ..., ... , IntPtr [] p, ... );

pBuffer is an IntPtr[] so pass it as the 3th parameter.

* cleanup unmanaged memory
for (int i= 0; i<LB_NUM_CAMERA S; ++i )
Marshal.FreeHGl obal ( 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_CAMERA S; ++i)
pBuffer[i] = Marshal.AllocHG lobal( LB_COLS * LB_ROWS * 4 );

* read data
public byte ReadData( int camera, int idx )
{
// TODO check if idx < rows*cols*4
return Marshal.ReadByt e ( pBuffer[camera], idx );
}

* write data
public void WriteData( int camera, int idx, byte value )
{
// TODO check if idx < rows*cols*4
Marshal.WriteBy te ( pBuffer[camera], idx, value );
}

HTH,
greetings
"Don" <ka**@wsdot.wa. gov> wrote in message
news:13******** *************** ***@posting.goo gle.com...
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:

ladybugConvertT oMultipleBGRU32 (
LadybugContext context,
const LadybugImage* pimage,
unsigned char* arpszDestBuffer s[ LADYBUG_NUM_CAM ERAS ],
LadybugImageInf o* pImageInfo );
It is used, in C++, as follows (some code chopped for brevety):

unsigned char* arpTextureBuffe rs[ LADYBUG_NUM_CAM ERAS ];
for(i = 0; i<LADYBUG_NUM_C AMERAS;i++)
{
arpTextureBuffe rs[i] =
new unsigned char[LADYBUG_RAW_IMA GE_COLS * LADYBUG_RAW_IMA GE_ROWS *
4];
}

error = ladybugConvertT oMultipleBGRU32 (
ladybug,
&image,
&arpTextureBuff ers[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 (&arpTextureBuf fers[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. */
LadybugVideoMod e videoMode;
/** Timestamp of this image. */
LadybugTimestam p timeStamp;
/** Image information for this image. */
LadybugImageInf o imageInfo;
/**
* Pointer to the actual image data. The data will be of length
* iRows * iCols * LADYBUG_NUM_CAM ERAS. 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 LadybugVideoMod e
{
/** 1024 x 768 x 6 cameras */
LADYBUG_VIDEOMO DE_LADYBUG_1024 x768x6,
/** 512 x 384 x 6 cameras */
LADYBUG_VIDEOMO DE_LADYBUG_512x 384x6,
/** 256 x 192 x 6 cameras */
LADYBUG_VIDEOMO DE_LADYBUG_256x 192x6,
/** 128 x 96 x 6 cameras */
LADYBUG_VIDEOMO DE_LADYBUG_128x 96x6,
/** Number of possible video modes. */
LADYBUG_NUM_VID EOMODES,
/** Hook for "any usable video mode." */
LADYBUG_VIDEOMO DE_ANY,

} LadybugVideoMod e;

/**
* 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 LadybugTimestam p
{
/** 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;

} LadybugTimestam p;

/**
* Out of band image information stored to the hard drive as part of
each
* image set at capture time.
*/
typedef struct LadybugImageInf o
{
/** 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 ulTimeMicroSeco nds;
/** 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 ];

} LadybugImageInf o;
The function I need to call follows:

/**
* Parse the 6 images in a LADYBUG_VIDEOMO DE_LADYBUG LadybugImage into
* 6 BGRU32 buffers. Color processing will use the current color
processing
* method.
*
* @param context The LadybugContext to access.
* @param arpszDestBuffer s 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 ladybugSetProce ssingCameras()) .
* @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 ladybugSetAlpha Masking( true ) again.
*/
LADYBUGDLL_API LadybugError
ladybugConvertT oMultipleBGRU32 (
LadybugContext context,
const LadybugImage* pimage,
unsigned char* arpszDestBuffer s[ LADYBUG_NUM_CAM ERAS ],
LadybugImageInf o* 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(La youtKind.Sequen tial)]
public struct LadyBugTimestam p
{
uint Seconds;
uint MicroSeconds;
uint CycleSeconds;
uint CycleCount;
}

public enum LadybugVideoMod e
{
LADYBUG_VIDEOMO DE_LADYBUG_1024 x768x6,
LADYBUG_VIDEOMO DE_LADYBUG_512x 384x6,
LADYBUG_VIDEOMO DE_LADYBUG_256x 192x6,
LADYBUG_VIDEOMO DE_LADYBUG_128x 96x6,
LADYBUG_NUM_VID EOMODES,
LADYBUG_VIDEOMO DE_ANY
}

[StructLayout(La youtKind.Sequen tial)]
public struct LadybugImageInf o
{
public uint Fingerprint;
public uint Version;
public uint TimeSeconds;
public uint TimeMicroSecond s;
public uint SequenceId;
public uint HRate;

[MarshalAs(Unman agedType.ByValA rray,SizeConst= 6)]
public uint[] GainAdjust;

public uint WhiteBalance;
public uint BayerGain;
public uint BayerMap;
public uint Brightness;
public uint Gamma;
public uint SerialNum;

[MarshalAs(Unman agedType.ByValA rray,SizeConst= 6)]
public uint[] Shutter;

[MarshalAs(Unman agedType.ByValA rray,SizeConst= 6)]
public uint[] Reserverd;

public LadybugImageInf o(int unused)
{ // constructor
GainAdjust = new byte[6];
Shutter = new byte[6];
Reserverd = new byte[6];
}
}

[StructLayout(St ructLayoutEnum. Sequential)]
public struct LadybugImage
{
public uint Cols;
public uint Rows;
public int videoMode; // cast VideModeEnums to int or parse from int
public LadybugTimeStam p timeStamp;
public LadybugImageInf o imageInfo;
public IntPtr pData;

[MarshalAs(Unman agedType.ByValA rray,SizeConst= 4)]
public uint[] Reserved;

public LadybugImage(in t unused)
{ // constructor
timeStamp = new LadybugTimeStam p();
imageInfo = new LadybugImageInf o(0);
Reserverd = new byte[4];
}
}

[DllImport(...)]
public static extern int ladybugConvertT oMultipleBGRU32 (
LadybugContext context,
ref LadybugImage image,
IntPtr[] pDestBuffers,
ref LadybugImageInf o ImageInfo );

public void test()
{
LadybugImagInfo ImageInfo = new LadybugImageInf o(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.AllocHG lobal(rows*cols *4);

// Call unmanaged function
ladybugConvertT oMultipleBGRU32 ( 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.HFreeGl obal( pDestBuffers[i] );
}

// If you allocated memory for Image.pImage then cleanup
Marshal.HFreeGl obal( 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.AllocHG lobal( 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.WriteBy te 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 ladybugConvertT oMultipleBGRU32 , 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 ladybugConvertT oMultipleBGRU32 _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 ladybugConvertT oMultipleBGRU32 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[] arpszDestBuffer s): 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
2340
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 correct, and if so, does anyone have an example ? Thanks !!
3
3092
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 PUNICODE_STRING ProviderName OUT HANDLE *ProviderHandle ) definition of the data types used are typedef LONG NTSTATUS, *PNTSTATUS typedef struct _UNICODE_STRING USHORT Length
1
273
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 context, const LadybugImage* pimage, unsigned char* arpszDestBuffers, LadybugImageInfo* pImageInfo );
1
1412
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 metadata for runtime but why to do it public? is code will run correctly if i make these types private for assembly? there is no way to do so from IDE or by some compiler option but i can
2
2059
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 managed point-of-view I've noticed that: 1) for each managed and unmanaged C function (not C++ classes) I get a public managed static method (defined on a 'Global Functions' class) in the generated assembly with an export name of the form
4
5724
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 collected. I also noticed that when replaced some of the existing MFC dialogs with managed winforms that everything is still running in the same app domain.( No context change) So my question is this, what are the performance differences in using...
5
1778
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
4784
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 call-back mechanism. These calls pass a string that contains a "command" and a pointer to a SafeArray that (depending on the command) either receives data from the ..Net application or provides data to the .Net application. This mechanism is...
4
1986
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 STL and a touch of MFC. It represents the back end to my applications and, among a number of other things, it performs all file I/O and data management operations (i.e. no GUI). Why would I consider porting it to C++/CLI when it works just...
0
10524
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10278
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9105
agi2029
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, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7594
isladogs
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6833
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5619
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4265
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3786
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2963
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.