Passing a struct with an array to C++ function 
Author Message
 Passing a struct with an array to C++ function

Hello,
I am trying to pass a struct to a C++ function.  The struct contains an
array of doubles.  C# doesn't like this.
The following struct is what I am trying to pass in:
public struct tagAGA10STRUCT
{
     /* corresponds to the control group in meter classes */
     public long lStatus ;   /* calculation status */
     public bool bForceUpdate;  /* signal to perform full calculation */

----- This is the offending double array ------------------
     public double[] adMixture; /* Composition in mole fraction */

     public double dPb ;      /* Contract base Pressure (Pa) */
     public double dTb ;     /* Contract base temperature  (K) */
     public double dPf ;      /* Absolute Pressure (Pa) */
     public double dTf ;     /* Flowing temperature (K) */
     // basic output from AGA 8 Detail method
     // Some other doubles left out.....

Quote:
}

I am trying to pass this to a C++ function with this signature...

DllExport double Crit(AGA10STRUCT *ptAGA10, double dPlenumVelocity)
{
     // variables local to function
    // members and methods left out...

Quote:
}

The error message I get is:
Additional information: Can not marshal field adMixture of type
CEESIGas.tagAGA10STRUCT: This type can not be marshaled as a structure
field.

I'm sure the solution lies somewhere in the Marshal class but this is beyond
my experience.  Can someone please help me here?

Thanks,
Tom C.



Mon, 17 Jan 2005 00:04:33 GMT  
 Passing a struct with an array to C++ function
Thomas,

    You will have to manually marshal the structure to unmanaged memory.
First off, your definition should be as follows:

public struct tagAGA10STRUCT
{
     /* corresponds to the control group in meter classes */
     public long lStatus ;   /* calculation status */
     public bool bForceUpdate;  /* signal to perform full calculation */

     public IntPtr adMixture; /* Composition in mole fraction */

     public double dPb ;      /* Contract base Pressure (Pa) */
     public double dTb ;     /* Contract base temperature  (K) */
     public double dPf ;      /* Absolute Pressure (Pa) */
     public double dTf ;     /* Flowing temperature (K) */
     // basic output from AGA 8 Detail method
     // Some other doubles left out.....

Quote:
}

    Then, before you pass the structure in, you create an instance.  Once
you create the instance, you will have to manually marshal the array.  Call
one of the methods on Marshal that allocates unmanaged memory
(AllocCoTaskMem works well).  The number of bytes you want to marshal is the
size of a double (easily obtained using Marshal.SizeOf) multiplied by the
elements in the array.  Once you have the IntPtr with the memory, cycle
through the elements of the array, and copy the double to the unmanaged
memory, using the Marshal.StructureToPtr method.  As you cycle through the
array, make sure you increment IntPtr by the size of ONE element so that you
write your values to the correct memory address.  When that is said and
done, set adMixture to the IntPtr, and marshal to the function.

    If these values change, then you will have to do the reverse.  Also, if
the array is resized, you have a problem, because you will have a memory
leak.

    Once the call is done, make sure to call Marshal.FreeCoTaskMem to free
the unmanaged memory.

    Hope this helps.

--
               - Nicholas Paldino [.NET MVP]


Quote:
> Hello,
> I am trying to pass a struct to a C++ function.  The struct contains an
> array of doubles.  C# doesn't like this.
> The following struct is what I am trying to pass in:
> public struct tagAGA10STRUCT
> {
>      /* corresponds to the control group in meter classes */
>      public long lStatus ;   /* calculation status */
>      public bool bForceUpdate;  /* signal to perform full calculation */

> ----- This is the offending double array ------------------
>      public double[] adMixture; /* Composition in mole fraction */

>      public double dPb ;      /* Contract base Pressure (Pa) */
>      public double dTb ;     /* Contract base temperature  (K) */
>      public double dPf ;      /* Absolute Pressure (Pa) */
>      public double dTf ;     /* Flowing temperature (K) */
>      // basic output from AGA 8 Detail method
>      // Some other doubles left out.....
> }

> I am trying to pass this to a C++ function with this signature...

> DllExport double Crit(AGA10STRUCT *ptAGA10, double dPlenumVelocity)
> {
>      // variables local to function
>     // members and methods left out...
> }

> The error message I get is:
> Additional information: Can not marshal field adMixture of type
> CEESIGas.tagAGA10STRUCT: This type can not be marshaled as a structure
> field.

> I'm sure the solution lies somewhere in the Marshal class but this is
beyond
> my experience.  Can someone please help me here?

> Thanks,
> Tom C.



Mon, 17 Jan 2005 01:00:14 GMT  
 Passing a struct with an array to C++ function
First, be sure
    public long lStatus ;   /* calculation status */
is really a >>64-Bit<< long in C#, else use 32-Bit 'int'.
 (also watch alignment)

And what is the exact C++ signature of following line ? :
   public double[] adMixture; /* Composition in mole fraction */

if it is a fixed sized array, use 'MarshalAs'
e.g. for >>10<< elements :

   [MarshalAs( UnmanagedType.ByValArray, SizeConst=10)]

   public double[] adMixture; /* Composition in mole fraction */

if it is a pointer to an array,
use IntPtr like Nicholas Paldino wrote.

--
  NETMaster  (Thomas Scheidegger)
  http://www.cetus-links.org/oo_csharp.html

Quote:

> I am trying to pass a struct to a C++ function.  The struct contains an
> array of doubles.  C# doesn't like this.
> The following struct is what I am trying to pass in:
> public struct tagAGA10STRUCT
> {
> ----- This is the offending double array ------------------
>      public double[] adMixture; /* Composition in mole fraction */
> }
> I am trying to pass this to a C++ function with this signature...
> The error message I get is:
> Additional information: Can not marshal field adMixture of type
> CEESIGas.tagAGA10STRUCT: This type can not be marshaled as a structure
> field.



Mon, 17 Jan 2005 01:41:01 GMT  
 Passing a struct with an array to C++ function
Here is the C++ Signature I'm trying to pass into:

DllExport double Crit(AGA10STRUCT *ptAGA10, double dPlenumVelocity)
{
     // variables local to function
    // Other stuff left out

Quote:
}



Quote:
> First, be sure
>     public long lStatus ;   /* calculation status */
> is really a >>64-Bit<< long in C#, else use 32-Bit 'int'.
>  (also watch alignment)

> And what is the exact C++ signature of following line ? :
>    public double[] adMixture; /* Composition in mole fraction */

> if it is a fixed sized array, use 'MarshalAs'
> e.g. for >>10<< elements :

>    [MarshalAs( UnmanagedType.ByValArray, SizeConst=10)]

>    public double[] adMixture; /* Composition in mole fraction */

> if it is a pointer to an array,
> use IntPtr like Nicholas Paldino wrote.

> --
>   NETMaster  (Thomas Scheidegger)
>   http://www.cetus-links.org/oo_csharp.html




- Show quoted text -

Quote:
> > I am trying to pass a struct to a C++ function.  The struct contains an
> > array of doubles.  C# doesn't like this.
> > The following struct is what I am trying to pass in:
> > public struct tagAGA10STRUCT
> > {
> > ----- This is the offending double array ------------------
> >      public double[] adMixture; /* Composition in mole fraction */
> > }
> > I am trying to pass this to a C++ function with this signature...
> > The error message I get is:
> > Additional information: Can not marshal field adMixture of type
> > CEESIGas.tagAGA10STRUCT: This type can not be marshaled as a structure
> > field.



Mon, 17 Jan 2005 02:41:30 GMT  
 Passing a struct with an array to C++ function
And also, the signature of the C++ code is

double adMixture[NUMBEROFCOMPONENTS] ; /* Composition in mole fraction */

Where the NUMBEROFCOMPONENTS = 21

Sorry I left that out.

Thanks again,


Quote:
> First, be sure
>     public long lStatus ;   /* calculation status */
> is really a >>64-Bit<< long in C#, else use 32-Bit 'int'.
>  (also watch alignment)

> And what is the exact C++ signature of following line ? :
>    public double[] adMixture; /* Composition in mole fraction */

> if it is a fixed sized array, use 'MarshalAs'
> e.g. for >>10<< elements :

>    [MarshalAs( UnmanagedType.ByValArray, SizeConst=10)]

>    public double[] adMixture; /* Composition in mole fraction */

> if it is a pointer to an array,
> use IntPtr like Nicholas Paldino wrote.

> --
>   NETMaster  (Thomas Scheidegger)
>   http://www.cetus-links.org/oo_csharp.html




- Show quoted text -

Quote:
> > I am trying to pass a struct to a C++ function.  The struct contains an
> > array of doubles.  C# doesn't like this.
> > The following struct is what I am trying to pass in:
> > public struct tagAGA10STRUCT
> > {
> > ----- This is the offending double array ------------------
> >      public double[] adMixture; /* Composition in mole fraction */
> > }
> > I am trying to pass this to a C++ function with this signature...
> > The error message I get is:
> > Additional information: Can not marshal field adMixture of type
> > CEESIGas.tagAGA10STRUCT: This type can not be marshaled as a structure
> > field.



Mon, 17 Jan 2005 02:50:40 GMT  
 Passing a struct with an array to C++ function
so you can use for NUMBEROFCOMPONENTS = 21 :

    [MarshalAs( UnmanagedType.ByValArray, SizeConst=21)]
   public double[] adMixture; /* Composition in mole fraction */

--
  NETMaster  (Thomas Scheidegger)
  http://www.cetus-links.org/oo_csharp.html

Quote:

> And also, the signature of the C++ code is
> double adMixture[NUMBEROFCOMPONENTS] ; /* Composition in mole fraction */
> Where the NUMBEROFCOMPONENTS = 21



Mon, 17 Jan 2005 03:16:19 GMT  
 Passing a struct with an array to C++ function
Works great now thanks to you and Nicholas.  Also, it was a 32 bit long not
a 64 bit.  I hate having to remember that all the time :)


Quote:
> so you can use for NUMBEROFCOMPONENTS = 21 :

>     [MarshalAs( UnmanagedType.ByValArray, SizeConst=21)]
>    public double[] adMixture; /* Composition in mole fraction */

> --
>   NETMaster  (Thomas Scheidegger)
>   http://www.cetus-links.org/oo_csharp.html




Quote:
> > And also, the signature of the C++ code is
> > double adMixture[NUMBEROFCOMPONENTS] ; /* Composition in mole fraction
*/
> > Where the NUMBEROFCOMPONENTS = 21



Mon, 17 Jan 2005 03:24:08 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. array of Struct passing into a function

2. Array of struct pass to function

3. pass a pointer to array of structs to functions

4. How to pass struct array to called function

5. function parameters to pass a VB string array to a C++ DLL

6. Passing an array of UDTs from a c++ client to c++ server

7. How to pass a struct to an unsigned char array

8. Passing array of struct

9. passing adress of second element in array of structs

10. How to pass a struct to an unsigned char array

11. Passing an array of structs

12. Passing an array of structs

 

 
Powered by phpBB® Forum Software