Marshaling a structure containing a aray of different structures 
Author Message
 Marshaling a structure containing a aray of different structures

Hi,

Im trying to marshal a structure that contains an array of another
structure. As you can see the tNSPropertyList contains an array of
tNSProperty structures. I have been able to make this work by copying all
the array values to an allocated memory buffer, then passing the pointer to
that memory in place of the array, but Im hoping someone out there knows of
a more elegant solution.

typedef struct _tNSProperty {
 LPCWSTR pName;
 DWORD dwType;
  LPCWSTR pValue;

Quote:
} tNSProperty;

typedef struct _tNSPropertyList {
 tNSProperty Property;
 struct _tNSPropertyList *pNext;

Quote:
} tNSPropertyList;

I have tried doing this, but I get a System.TypeLoadException at runtime
complaining about the array member.

  [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
   public class tNSProperty
  {
   public string Name;           // LPCWSTR Name
   public uint Type;           // DWORD Type
   public string Value;          //  LPCWSTR pValue
  }

  [StructLayout(LayoutKind.Sequential)]
   public class tNSPropertyList
  {
   public uint PropertyCount;         // DWORD PropertyCount
   public tNSProperty[] Properties;       // tNSProperty *Properties
  }

TIA
-Mike



Sat, 18 Dec 2004 02:42:32 GMT  
 Marshaling a structure containing a aray of different structures
Mike,

    Unfortunately, that is as about as elegant as it gets.  The only thing
that might help would be to use the StructureToPtr method on the Marshal
class to marshal the structure to unmanaged memory for you instead of doing
it yourself.  You will still have to allocate the unmanged memory.

    Hope this helps.

--
               - Nicholas Paldino [.NET MVP]


Quote:
> Hi,

> Im trying to marshal a structure that contains an array of another
> structure. As you can see the tNSPropertyList contains an array of
> tNSProperty structures. I have been able to make this work by copying all
> the array values to an allocated memory buffer, then passing the pointer
to
> that memory in place of the array, but Im hoping someone out there knows
of
> a more elegant solution.

> typedef struct _tNSProperty {
>  LPCWSTR pName;
>  DWORD dwType;
>   LPCWSTR pValue;
> } tNSProperty;

> typedef struct _tNSPropertyList {
>  tNSProperty Property;
>  struct _tNSPropertyList *pNext;
> } tNSPropertyList;

> I have tried doing this, but I get a System.TypeLoadException at runtime
> complaining about the array member.

>   [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
>    public class tNSProperty
>   {
>    public string Name;           // LPCWSTR Name
>    public uint Type;           // DWORD Type
>    public string Value;          //  LPCWSTR pValue
>   }

>   [StructLayout(LayoutKind.Sequential)]
>    public class tNSPropertyList
>   {
>    public uint PropertyCount;         // DWORD PropertyCount
>    public tNSProperty[] Properties;       // tNSProperty *Properties
>   }

> TIA
> -Mike



Sat, 18 Dec 2004 03:16:18 GMT  
 Marshaling a structure containing a aray of different structures
Thanks Nicholas. Is there a document on MSDN that explains why this cant be
done?

-Mike



Quote:
> Mike,

>     Unfortunately, that is as about as elegant as it gets.  The only thing
> that might help would be to use the StructureToPtr method on the Marshal
> class to marshal the structure to unmanaged memory for you instead of
doing
> it yourself.  You will still have to allocate the unmanged memory.

>     Hope this helps.

> --
>                - Nicholas Paldino [.NET MVP]



> > Hi,

> > Im trying to marshal a structure that contains an array of another
> > structure. As you can see the tNSPropertyList contains an array of
> > tNSProperty structures. I have been able to make this work by copying
all
> > the array values to an allocated memory buffer, then passing the pointer
> to
> > that memory in place of the array, but Im hoping someone out there knows
> of
> > a more elegant solution.

> > typedef struct _tNSProperty {
> >  LPCWSTR pName;
> >  DWORD dwType;
> >   LPCWSTR pValue;
> > } tNSProperty;

> > typedef struct _tNSPropertyList {
> >  tNSProperty Property;
> >  struct _tNSPropertyList *pNext;
> > } tNSPropertyList;

> > I have tried doing this, but I get a System.TypeLoadException at runtime
> > complaining about the array member.

> >   [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
> >    public class tNSProperty
> >   {
> >    public string Name;           // LPCWSTR Name
> >    public uint Type;           // DWORD Type
> >    public string Value;          //  LPCWSTR pValue
> >   }

> >   [StructLayout(LayoutKind.Sequential)]
> >    public class tNSPropertyList
> >   {
> >    public uint PropertyCount;         // DWORD PropertyCount
> >    public tNSProperty[] Properties;       // tNSProperty *Properties
> >   }

> > TIA
> > -Mike



Sat, 18 Dec 2004 03:24:03 GMT  
 Marshaling a structure containing a aray of different structures
Mike,

    I believe that it comes down to the fact that there is no descriptor
telling the length of the array after the marshalling has occured.
SAFEARRAYS have a length descriptor embedded in them, so you can marshal
them anywhere you want really.  However, with C-style arrays, there is
nothing that tells the interop layer how many items are in the array
embedded in the structure, so you can't know how much memory to read from
the address passed back.

    For more information, you can look at the section of the .NET framework
documentation titled "Default Marshaling for Arrays".

--
               - Nicholas Paldino [.NET MVP]


Quote:
> Thanks Nicholas. Is there a document on MSDN that explains why this cant
be
> done?

> -Mike


wrote

> > Mike,

> >     Unfortunately, that is as about as elegant as it gets.  The only
thing
> > that might help would be to use the StructureToPtr method on the Marshal
> > class to marshal the structure to unmanaged memory for you instead of
> doing
> > it yourself.  You will still have to allocate the unmanged memory.

> >     Hope this helps.

> > --
> >                - Nicholas Paldino [.NET MVP]



> > > Hi,

> > > Im trying to marshal a structure that contains an array of another
> > > structure. As you can see the tNSPropertyList contains an array of
> > > tNSProperty structures. I have been able to make this work by copying
> all
> > > the array values to an allocated memory buffer, then passing the
pointer
> > to
> > > that memory in place of the array, but Im hoping someone out there
knows
> > of
> > > a more elegant solution.

> > > typedef struct _tNSProperty {
> > >  LPCWSTR pName;
> > >  DWORD dwType;
> > >   LPCWSTR pValue;
> > > } tNSProperty;

> > > typedef struct _tNSPropertyList {
> > >  tNSProperty Property;
> > >  struct _tNSPropertyList *pNext;
> > > } tNSPropertyList;

> > > I have tried doing this, but I get a System.TypeLoadException at
runtime
> > > complaining about the array member.

> > >   [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
> > >    public class tNSProperty
> > >   {
> > >    public string Name;           // LPCWSTR Name
> > >    public uint Type;           // DWORD Type
> > >    public string Value;          //  LPCWSTR pValue
> > >   }

> > >   [StructLayout(LayoutKind.Sequential)]
> > >    public class tNSPropertyList
> > >   {
> > >    public uint PropertyCount;         // DWORD PropertyCount
> > >    public tNSProperty[] Properties;       // tNSProperty *Properties
> > >   }

> > > TIA
> > > -Mike



Sat, 18 Dec 2004 03:33:06 GMT  
 Marshaling a structure containing a aray of different structures


Quote:
> Hi,

> Im trying to marshal a structure that contains an array of another
> structure. As you can see the tNSPropertyList contains an array of
> tNSProperty structures. I have been able to make this work by copying all
> the array values to an allocated memory buffer, then passing the pointer
to
> that memory in place of the array, but Im hoping someone out there knows
of
> a more elegant solution.

...
>   [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
>    public class tNSProperty
>   {
>    public string Name;           // LPCWSTR Name
>    public uint Type;           // DWORD Type
>    public string Value;          //  LPCWSTR pValue
>   }

>   [StructLayout(LayoutKind.Sequential)]
>    public class tNSPropertyList
>   {
>    public uint PropertyCount;         // DWORD PropertyCount

Not sure I'd call it elegant but I've used this for arrays of chars. Might
work for a struct array.  You need to know the size of the array at compile
time to set XXX so this may not help in your case. This is from a message
posted a while back that had a rawSerialize/deserialize routine in it.  I'll
dig up a reference to the post if you're interested.

[MarshallAs( UnmanagedType.ByValArray, SizeConst=XXX )]

- Show quoted text -

Quote:
>    public tNSProperty[] Properties;       // tNSProperty *Properties
>   }

> TIA
> -Mike



Sat, 18 Dec 2004 04:40:37 GMT  
 
 [ 5 post ] 

 Relevant Pages 

1. Converting byte[] to structure without Marshal?

2. Marshaling structures with arrays

3. Marshal problem with pointers to structures

4. Pointers to Structure that contains pointer to Function

5. printing a string contained in a structure

6. reading a structure containing pointers

7. Sorting a last names that are contained within a structure

8. structure containing pointer to char over the network

9. How Do I fwrite() and fread() A Structure that contains pointers to dynamic data

10. A question about a structure containing ':'

11. Size of structure containing char fields

12. self contained pointers to structures

 

 
Powered by phpBB® Forum Software