[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.interop

Mashaling array of structures... not working I don't know why

Pedro Mota

2/26/2007 5:52:00 PM

Hello,

I'm having the following problem and I need some help from you:

I've a dll writen in C that has one function that has a parameter that's an
array of structures of type T_MyStruct.

The structure T_MyStruct has just one field, being an array of 7 stuctures
of type T_A.

The structure T_A has 2 fields. One is an integer and the other one is a
union of structures (T_StructUnion).

The union T_StructUnion is composed by 2 structures: structure T_B and
structure T_C.

Booth structures, T_B and T_C, have one field that is a byte array of size 50.


I declared it in C# as follows:


[StructLayout(LayoutKind.Sequential)]
public struct T_B{

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
byte[] fieldB1;
}

[StructLayout(LayoutKind.Sequential)]
public struct T_C{

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
byte[] fieldC1;

}

[StructLayout(LayoutKind.Explicit)]
public struct T_StructUnion{

[System.Runtime.InteropServices.FieldOffset(0)]
public T_B fieldUnion1;

[System.Runtime.InteropServices.FieldOffset(0)]
public T_C fieldUnion2;
}


[StructLayout(LayoutKind.Sequential)]
public struct T_A{

public int fieldA1;

public StructUnion fieldA2;
}



[StructLayout(LayoutKind.Sequential)]
public T_MyStruct{

[MarshalAs(UnmanagedType.ByValArray,SizeConst = 7)]
public T_A[] myField;
}


[DllImport("mylib.dll", EntryPoint = "MyMethod", SetLastError = true)]
public static extern int MyMethod([In,Out] T_MyStruct[] myStructures);


The declaration in C languag is equivalent. The only difference is that the
fields of structures T_B and T_C are char[100], but I declared
them as byte[] in C#. The problem is not coming from this because i've other
structures defined like this and working good.

The problem is that when I invoke the method I've this error written in the
console:
"Cannot marshal field 'myField' of type 'T_MyStruct': There is no marshaling
support for this type.
Failing when marshaling from C# to C.

But if I declare the field in structure T_B and T_C as integers the error
disapears, failing then internally in the DLL because the
types are not correct.

Can someone waste some time helping me?
This is very imporant to me and I don't know why it's not working.

5 Answers

Michael Phillips, Jr.

2/26/2007 7:52:00 PM

0

> This is very imporant to me and I don't know why it's not working.

It is not working because the default marshaler does not know how to format
the unmanaged memory that represents your structure in C.

You have to help it by either creating a custom marshaler or a wrapper
function that takes the memory from your managed structures and copies them
exactly to the memory layout that the MyMethod method expects.

It may be tedious but it can be done. You start by allocating unmanaged
memory with the marshaler class to represent the layout of your C
struct(i.e., T_MyStruct[] ).

This chunk of memory will be held in an IntPtr and its size will be the
total of 7 * sizeof(T_MyStruct).

You set up a loop and use the marshal methods to move the managed memory to
the unmanaged memory. You must keep track of the index into the InPtr's
byte array as you are copying the structs.

When you are done you pass a ref to the IntPtr to your MyMethod method.


"Pedro Mota" <Pedro Mota@discussions.microsoft.com> wrote in message
news:3D022598-FB2D-44F7-84C6-140084553F8E@microsoft.com...
> Hello,
>
> I'm having the following problem and I need some help from you:
>
> I've a dll writen in C that has one function that has a parameter that's
> an
> array of structures of type T_MyStruct.
>
> The structure T_MyStruct has just one field, being an array of 7 stuctures
> of type T_A.
>
> The structure T_A has 2 fields. One is an integer and the other one is a
> union of structures (T_StructUnion).
>
> The union T_StructUnion is composed by 2 structures: structure T_B and
> structure T_C.
>
> Booth structures, T_B and T_C, have one field that is a byte array of size
> 50.
>
>
> I declared it in C# as follows:
>
>
> [StructLayout(LayoutKind.Sequential)]
> public struct T_B{
>
> [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
> byte[] fieldB1;
> }
>
> [StructLayout(LayoutKind.Sequential)]
> public struct T_C{
>
> [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
> byte[] fieldC1;
>
> }
>
> [StructLayout(LayoutKind.Explicit)]
> public struct T_StructUnion{
>
> [System.Runtime.InteropServices.FieldOffset(0)]
> public T_B fieldUnion1;
>
> [System.Runtime.InteropServices.FieldOffset(0)]
> public T_C fieldUnion2;
> }
>
>
> [StructLayout(LayoutKind.Sequential)]
> public struct T_A{
>
> public int fieldA1;
>
> public StructUnion fieldA2;
> }
>
>
>
> [StructLayout(LayoutKind.Sequential)]
> public T_MyStruct{
>
> [MarshalAs(UnmanagedType.ByValArray,SizeConst = 7)]
> public T_A[] myField;
> }
>
>
> [DllImport("mylib.dll", EntryPoint = "MyMethod", SetLastError = true)]
> public static extern int MyMethod([In,Out] T_MyStruct[] myStructures);
>
>
> The declaration in C languag is equivalent. The only difference is that
> the
> fields of structures T_B and T_C are char[100], but I declared
> them as byte[] in C#. The problem is not coming from this because i've
> other
> structures defined like this and working good.
>
> The problem is that when I invoke the method I've this error written in
> the
> console:
> "Cannot marshal field 'myField' of type 'T_MyStruct': There is no
> marshaling
> support for this type.
> Failing when marshaling from C# to C.
>
> But if I declare the field in structure T_B and T_C as integers the error
> disapears, failing then internally in the DLL because the
> types are not correct.
>
> Can someone waste some time helping me?
> This is very imporant to me and I don't know why it's not working.
>


Pedro Mota

2/27/2007 1:20:00 PM

0

Thank you for your reply Michael.

I don't understant why the default marshaler knows how to marshall when the
fields of struct T_B and T_C are int's and does not know when the fields are
byte[].
Do you know why?

I've not to many expirience with .NET Interop, most of the work I've done
were relatively simple.

I've had never done a custom marshaller and I'll have to check those
functions that alloc and move memory.

I'll try to follow your aproach.

Thanks
Pedro

"Michael Phillips, Jr." wrote:

> > This is very imporant to me and I don't know why it's not working.
>
> It is not working because the default marshaler does not know how to format
> the unmanaged memory that represents your structure in C.
>
> You have to help it by either creating a custom marshaler or a wrapper
> function that takes the memory from your managed structures and copies them
> exactly to the memory layout that the MyMethod method expects.
>
> It may be tedious but it can be done. You start by allocating unmanaged
> memory with the marshaler class to represent the layout of your C
> struct(i.e., T_MyStruct[] ).
>
> This chunk of memory will be held in an IntPtr and its size will be the
> total of 7 * sizeof(T_MyStruct).
>
> You set up a loop and use the marshal methods to move the managed memory to
> the unmanaged memory. You must keep track of the index into the InPtr's
> byte array as you are copying the structs.
>
> When you are done you pass a ref to the IntPtr to your MyMethod method.
>
>
> "Pedro Mota" <Pedro Mota@discussions.microsoft.com> wrote in message
> news:3D022598-FB2D-44F7-84C6-140084553F8E@microsoft.com...
> > Hello,
> >
> > I'm having the following problem and I need some help from you:
> >
> > I've a dll writen in C that has one function that has a parameter that's
> > an
> > array of structures of type T_MyStruct.
> >
> > The structure T_MyStruct has just one field, being an array of 7 stuctures
> > of type T_A.
> >
> > The structure T_A has 2 fields. One is an integer and the other one is a
> > union of structures (T_StructUnion).
> >
> > The union T_StructUnion is composed by 2 structures: structure T_B and
> > structure T_C.
> >
> > Booth structures, T_B and T_C, have one field that is a byte array of size
> > 50.
> >
> >
> > I declared it in C# as follows:
> >
> >
> > [StructLayout(LayoutKind.Sequential)]
> > public struct T_B{
> >
> > [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
> > byte[] fieldB1;
> > }
> >
> > [StructLayout(LayoutKind.Sequential)]
> > public struct T_C{
> >
> > [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
> > byte[] fieldC1;
> >
> > }
> >
> > [StructLayout(LayoutKind.Explicit)]
> > public struct T_StructUnion{
> >
> > [System.Runtime.InteropServices.FieldOffset(0)]
> > public T_B fieldUnion1;
> >
> > [System.Runtime.InteropServices.FieldOffset(0)]
> > public T_C fieldUnion2;
> > }
> >
> >
> > [StructLayout(LayoutKind.Sequential)]
> > public struct T_A{
> >
> > public int fieldA1;
> >
> > public StructUnion fieldA2;
> > }
> >
> >
> >
> > [StructLayout(LayoutKind.Sequential)]
> > public T_MyStruct{
> >
> > [MarshalAs(UnmanagedType.ByValArray,SizeConst = 7)]
> > public T_A[] myField;
> > }
> >
> >
> > [DllImport("mylib.dll", EntryPoint = "MyMethod", SetLastError = true)]
> > public static extern int MyMethod([In,Out] T_MyStruct[] myStructures);
> >
> >
> > The declaration in C languag is equivalent. The only difference is that
> > the
> > fields of structures T_B and T_C are char[100], but I declared
> > them as byte[] in C#. The problem is not coming from this because i've
> > other
> > structures defined like this and working good.
> >
> > The problem is that when I invoke the method I've this error written in
> > the
> > console:
> > "Cannot marshal field 'myField' of type 'T_MyStruct': There is no
> > marshaling
> > support for this type.
> > Failing when marshaling from C# to C.
> >
> > But if I declare the field in structure T_B and T_C as integers the error
> > disapears, failing then internally in the DLL because the
> > types are not correct.
> >
> > Can someone waste some time helping me?
> > This is very imporant to me and I don't know why it's not working.
> >
>
>
>

Michael Phillips, Jr.

2/27/2007 3:43:00 PM

0

I have not tried to play around with your structs. I do not know why the
marshaler is unable to understand your struct declarations.

Your structs add a level of complexity with unions. You could try to
disassemble the code to see how the "IL" disassembly is internally coding
your structs.

You could try to simply your struct declarations until you able to pinpoint
where the compiler fails to understand how to marshal the struct.

You could also change your design to use VARIANTS and SAFEARRAYS. Then your
code will marshal without problems with all of the CLR languages.

Check out my post in this newsgroup for "How to marshal complex data
structures" for example code that may help you.


"Pedro Mota" <PedroMota@discussions.microsoft.com> wrote in message
news:137ED9FE-19AE-45BC-9084-17E211EE00AB@microsoft.com...
> Thank you for your reply Michael.
>
> I don't understant why the default marshaler knows how to marshall when
> the
> fields of struct T_B and T_C are int's and does not know when the fields
> are
> byte[].
> Do you know why?
>
> I've not to many expirience with .NET Interop, most of the work I've done
> were relatively simple.
>
> I've had never done a custom marshaller and I'll have to check those
> functions that alloc and move memory.
>
> I'll try to follow your aproach.
>
> Thanks
> Pedro
>
> "Michael Phillips, Jr." wrote:
>
>> > This is very imporant to me and I don't know why it's not working.
>>
>> It is not working because the default marshaler does not know how to
>> format
>> the unmanaged memory that represents your structure in C.
>>
>> You have to help it by either creating a custom marshaler or a wrapper
>> function that takes the memory from your managed structures and copies
>> them
>> exactly to the memory layout that the MyMethod method expects.
>>
>> It may be tedious but it can be done. You start by allocating unmanaged
>> memory with the marshaler class to represent the layout of your C
>> struct(i.e., T_MyStruct[] ).
>>
>> This chunk of memory will be held in an IntPtr and its size will be the
>> total of 7 * sizeof(T_MyStruct).
>>
>> You set up a loop and use the marshal methods to move the managed memory
>> to
>> the unmanaged memory. You must keep track of the index into the InPtr's
>> byte array as you are copying the structs.
>>
>> When you are done you pass a ref to the IntPtr to your MyMethod method.
>>
>>
>> "Pedro Mota" <Pedro Mota@discussions.microsoft.com> wrote in message
>> news:3D022598-FB2D-44F7-84C6-140084553F8E@microsoft.com...
>> > Hello,
>> >
>> > I'm having the following problem and I need some help from you:
>> >
>> > I've a dll writen in C that has one function that has a parameter
>> > that's
>> > an
>> > array of structures of type T_MyStruct.
>> >
>> > The structure T_MyStruct has just one field, being an array of 7
>> > stuctures
>> > of type T_A.
>> >
>> > The structure T_A has 2 fields. One is an integer and the other one is
>> > a
>> > union of structures (T_StructUnion).
>> >
>> > The union T_StructUnion is composed by 2 structures: structure T_B and
>> > structure T_C.
>> >
>> > Booth structures, T_B and T_C, have one field that is a byte array of
>> > size
>> > 50.
>> >
>> >
>> > I declared it in C# as follows:
>> >
>> >
>> > [StructLayout(LayoutKind.Sequential)]
>> > public struct T_B{
>> >
>> > [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
>> > byte[] fieldB1;
>> > }
>> >
>> > [StructLayout(LayoutKind.Sequential)]
>> > public struct T_C{
>> >
>> > [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
>> > byte[] fieldC1;
>> >
>> > }
>> >
>> > [StructLayout(LayoutKind.Explicit)]
>> > public struct T_StructUnion{
>> >
>> > [System.Runtime.InteropServices.FieldOffset(0)]
>> > public T_B fieldUnion1;
>> >
>> > [System.Runtime.InteropServices.FieldOffset(0)]
>> > public T_C fieldUnion2;
>> > }
>> >
>> >
>> > [StructLayout(LayoutKind.Sequential)]
>> > public struct T_A{
>> >
>> > public int fieldA1;
>> >
>> > public StructUnion fieldA2;
>> > }
>> >
>> >
>> >
>> > [StructLayout(LayoutKind.Sequential)]
>> > public T_MyStruct{
>> >
>> > [MarshalAs(UnmanagedType.ByValArray,SizeConst = 7)]
>> > public T_A[] myField;
>> > }
>> >
>> >
>> > [DllImport("mylib.dll", EntryPoint = "MyMethod", SetLastError = true)]
>> > public static extern int MyMethod([In,Out] T_MyStruct[] myStructures);
>> >
>> >
>> > The declaration in C languag is equivalent. The only difference is that
>> > the
>> > fields of structures T_B and T_C are char[100], but I declared
>> > them as byte[] in C#. The problem is not coming from this because i've
>> > other
>> > structures defined like this and working good.
>> >
>> > The problem is that when I invoke the method I've this error written in
>> > the
>> > console:
>> > "Cannot marshal field 'myField' of type 'T_MyStruct': There is no
>> > marshaling
>> > support for this type.
>> > Failing when marshaling from C# to C.
>> >
>> > But if I declare the field in structure T_B and T_C as integers the
>> > error
>> > disapears, failing then internally in the DLL because the
>> > types are not correct.
>> >
>> > Can someone waste some time helping me?
>> > This is very imporant to me and I don't know why it's not working.
>> >
>>
>>
>>


Pedro Mota

3/1/2007 5:21:00 PM

0

Hi,

I made a mistake, that's why it was not working, but I didn't figured it out
at first. Just after a long debug session I saw the cause of the problem.

In fact de P/Invoke service can marshall the example that I described.
I posted an example of a more complex real situation that I have in my
current project.

The mistake was that I forgot to set the attribute MarshalAs in one the
byte[] fields saying the length of the array. It was inside a comment!!!

Problem solved. It is working on a win32 desktop environment.

But now I have another problem: it's not working on the .NET Compact
Framework.
When the P/Invoke calls the native library it throws an
OutOfMemoryException. The native method isn't called!

What are the memory constraints in the .NET Compact Framework?

"Michael Phillips, Jr." wrote:

> I have not tried to play around with your structs. I do not know why the
> marshaler is unable to understand your struct declarations.
>
> Your structs add a level of complexity with unions. You could try to
> disassemble the code to see how the "IL" disassembly is internally coding
> your structs.
>
> You could try to simply your struct declarations until you able to pinpoint
> where the compiler fails to understand how to marshal the struct.
>
> You could also change your design to use VARIANTS and SAFEARRAYS. Then your
> code will marshal without problems with all of the CLR languages.
>
> Check out my post in this newsgroup for "How to marshal complex data
> structures" for example code that may help you.
>
>
> "Pedro Mota" <PedroMota@discussions.microsoft.com> wrote in message
> news:137ED9FE-19AE-45BC-9084-17E211EE00AB@microsoft.com...
> > Thank you for your reply Michael.
> >
> > I don't understant why the default marshaler knows how to marshall when
> > the
> > fields of struct T_B and T_C are int's and does not know when the fields
> > are
> > byte[].
> > Do you know why?
> >
> > I've not to many expirience with .NET Interop, most of the work I've done
> > were relatively simple.
> >
> > I've had never done a custom marshaller and I'll have to check those
> > functions that alloc and move memory.
> >
> > I'll try to follow your aproach.
> >
> > Thanks
> > Pedro
> >
> > "Michael Phillips, Jr." wrote:
> >
> >> > This is very imporant to me and I don't know why it's not working.
> >>
> >> It is not working because the default marshaler does not know how to
> >> format
> >> the unmanaged memory that represents your structure in C.
> >>
> >> You have to help it by either creating a custom marshaler or a wrapper
> >> function that takes the memory from your managed structures and copies
> >> them
> >> exactly to the memory layout that the MyMethod method expects.
> >>
> >> It may be tedious but it can be done. You start by allocating unmanaged
> >> memory with the marshaler class to represent the layout of your C
> >> struct(i.e., T_MyStruct[] ).
> >>
> >> This chunk of memory will be held in an IntPtr and its size will be the
> >> total of 7 * sizeof(T_MyStruct).
> >>
> >> You set up a loop and use the marshal methods to move the managed memory
> >> to
> >> the unmanaged memory. You must keep track of the index into the InPtr's
> >> byte array as you are copying the structs.
> >>
> >> When you are done you pass a ref to the IntPtr to your MyMethod method.
> >>
> >>
> >> "Pedro Mota" <Pedro Mota@discussions.microsoft.com> wrote in message
> >> news:3D022598-FB2D-44F7-84C6-140084553F8E@microsoft.com...
> >> > Hello,
> >> >
> >> > I'm having the following problem and I need some help from you:
> >> >
> >> > I've a dll writen in C that has one function that has a parameter
> >> > that's
> >> > an
> >> > array of structures of type T_MyStruct.
> >> >
> >> > The structure T_MyStruct has just one field, being an array of 7
> >> > stuctures
> >> > of type T_A.
> >> >
> >> > The structure T_A has 2 fields. One is an integer and the other one is
> >> > a
> >> > union of structures (T_StructUnion).
> >> >
> >> > The union T_StructUnion is composed by 2 structures: structure T_B and
> >> > structure T_C.
> >> >
> >> > Booth structures, T_B and T_C, have one field that is a byte array of
> >> > size
> >> > 50.
> >> >
> >> >
> >> > I declared it in C# as follows:
> >> >
> >> >
> >> > [StructLayout(LayoutKind.Sequential)]
> >> > public struct T_B{
> >> >
> >> > [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
> >> > byte[] fieldB1;
> >> > }
> >> >
> >> > [StructLayout(LayoutKind.Sequential)]
> >> > public struct T_C{
> >> >
> >> > [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
> >> > byte[] fieldC1;
> >> >
> >> > }
> >> >
> >> > [StructLayout(LayoutKind.Explicit)]
> >> > public struct T_StructUnion{
> >> >
> >> > [System.Runtime.InteropServices.FieldOffset(0)]
> >> > public T_B fieldUnion1;
> >> >
> >> > [System.Runtime.InteropServices.FieldOffset(0)]
> >> > public T_C fieldUnion2;
> >> > }
> >> >
> >> >
> >> > [StructLayout(LayoutKind.Sequential)]
> >> > public struct T_A{
> >> >
> >> > public int fieldA1;
> >> >
> >> > public StructUnion fieldA2;
> >> > }
> >> >
> >> >
> >> >
> >> > [StructLayout(LayoutKind.Sequential)]
> >> > public T_MyStruct{
> >> >
> >> > [MarshalAs(UnmanagedType.ByValArray,SizeConst = 7)]
> >> > public T_A[] myField;
> >> > }
> >> >
> >> >
> >> > [DllImport("mylib.dll", EntryPoint = "MyMethod", SetLastError = true)]
> >> > public static extern int MyMethod([In,Out] T_MyStruct[] myStructures);
> >> >
> >> >
> >> > The declaration in C languag is equivalent. The only difference is that
> >> > the
> >> > fields of structures T_B and T_C are char[100], but I declared
> >> > them as byte[] in C#. The problem is not coming from this because i've
> >> > other
> >> > structures defined like this and working good.
> >> >
> >> > The problem is that when I invoke the method I've this error written in
> >> > the
> >> > console:
> >> > "Cannot marshal field 'myField' of type 'T_MyStruct': There is no
> >> > marshaling
> >> > support for this type.
> >> > Failing when marshaling from C# to C.
> >> >
> >> > But if I declare the field in structure T_B and T_C as integers the
> >> > error
> >> > disapears, failing then internally in the DLL because the
> >> > types are not correct.
> >> >
> >> > Can someone waste some time helping me?
> >> > This is very imporant to me and I don't know why it's not working.
> >> >
> >>
> >>
> >>
>
>
>

Michael Phillips, Jr.

3/2/2007 2:38:00 PM

0

I have not worked with the compact framework. I suggest that you check the
MSDN documentation for the limitations:
http://msdn2.microsoft.com/en-us/library/aa4...


"Pedro Mota" <PedroMota@discussions.microsoft.com> wrote in message
news:46EF666F-27A1-40EC-906B-CE59D6DE93C0@microsoft.com...
> Hi,
>
> I made a mistake, that's why it was not working, but I didn't figured it
> out
> at first. Just after a long debug session I saw the cause of the problem.
>
> In fact de P/Invoke service can marshall the example that I described.
> I posted an example of a more complex real situation that I have in my
> current project.
>
> The mistake was that I forgot to set the attribute MarshalAs in one the
> byte[] fields saying the length of the array. It was inside a comment!!!
>
> Problem solved. It is working on a win32 desktop environment.
>
> But now I have another problem: it's not working on the .NET Compact
> Framework.
> When the P/Invoke calls the native library it throws an
> OutOfMemoryException. The native method isn't called!
>
> What are the memory constraints in the .NET Compact Framework?
>
> "Michael Phillips, Jr." wrote:
>
>> I have not tried to play around with your structs. I do not know why the
>> marshaler is unable to understand your struct declarations.
>>
>> Your structs add a level of complexity with unions. You could try to
>> disassemble the code to see how the "IL" disassembly is internally coding
>> your structs.
>>
>> You could try to simply your struct declarations until you able to
>> pinpoint
>> where the compiler fails to understand how to marshal the struct.
>>
>> You could also change your design to use VARIANTS and SAFEARRAYS. Then
>> your
>> code will marshal without problems with all of the CLR languages.
>>
>> Check out my post in this newsgroup for "How to marshal complex data
>> structures" for example code that may help you.
>>
>>
>> "Pedro Mota" <PedroMota@discussions.microsoft.com> wrote in message
>> news:137ED9FE-19AE-45BC-9084-17E211EE00AB@microsoft.com...
>> > Thank you for your reply Michael.
>> >
>> > I don't understant why the default marshaler knows how to marshall when
>> > the
>> > fields of struct T_B and T_C are int's and does not know when the
>> > fields
>> > are
>> > byte[].
>> > Do you know why?
>> >
>> > I've not to many expirience with .NET Interop, most of the work I've
>> > done
>> > were relatively simple.
>> >
>> > I've had never done a custom marshaller and I'll have to check those
>> > functions that alloc and move memory.
>> >
>> > I'll try to follow your aproach.
>> >
>> > Thanks
>> > Pedro
>> >
>> > "Michael Phillips, Jr." wrote:
>> >
>> >> > This is very imporant to me and I don't know why it's not working.
>> >>
>> >> It is not working because the default marshaler does not know how to
>> >> format
>> >> the unmanaged memory that represents your structure in C.
>> >>
>> >> You have to help it by either creating a custom marshaler or a wrapper
>> >> function that takes the memory from your managed structures and copies
>> >> them
>> >> exactly to the memory layout that the MyMethod method expects.
>> >>
>> >> It may be tedious but it can be done. You start by allocating
>> >> unmanaged
>> >> memory with the marshaler class to represent the layout of your C
>> >> struct(i.e., T_MyStruct[] ).
>> >>
>> >> This chunk of memory will be held in an IntPtr and its size will be
>> >> the
>> >> total of 7 * sizeof(T_MyStruct).
>> >>
>> >> You set up a loop and use the marshal methods to move the managed
>> >> memory
>> >> to
>> >> the unmanaged memory. You must keep track of the index into the
>> >> InPtr's
>> >> byte array as you are copying the structs.
>> >>
>> >> When you are done you pass a ref to the IntPtr to your MyMethod
>> >> method.
>> >>
>> >>
>> >> "Pedro Mota" <Pedro Mota@discussions.microsoft.com> wrote in message
>> >> news:3D022598-FB2D-44F7-84C6-140084553F8E@microsoft.com...
>> >> > Hello,
>> >> >
>> >> > I'm having the following problem and I need some help from you:
>> >> >
>> >> > I've a dll writen in C that has one function that has a parameter
>> >> > that's
>> >> > an
>> >> > array of structures of type T_MyStruct.
>> >> >
>> >> > The structure T_MyStruct has just one field, being an array of 7
>> >> > stuctures
>> >> > of type T_A.
>> >> >
>> >> > The structure T_A has 2 fields. One is an integer and the other one
>> >> > is
>> >> > a
>> >> > union of structures (T_StructUnion).
>> >> >
>> >> > The union T_StructUnion is composed by 2 structures: structure T_B
>> >> > and
>> >> > structure T_C.
>> >> >
>> >> > Booth structures, T_B and T_C, have one field that is a byte array
>> >> > of
>> >> > size
>> >> > 50.
>> >> >
>> >> >
>> >> > I declared it in C# as follows:
>> >> >
>> >> >
>> >> > [StructLayout(LayoutKind.Sequential)]
>> >> > public struct T_B{
>> >> >
>> >> > [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
>> >> > byte[] fieldB1;
>> >> > }
>> >> >
>> >> > [StructLayout(LayoutKind.Sequential)]
>> >> > public struct T_C{
>> >> >
>> >> > [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)]
>> >> > byte[] fieldC1;
>> >> >
>> >> > }
>> >> >
>> >> > [StructLayout(LayoutKind.Explicit)]
>> >> > public struct T_StructUnion{
>> >> >
>> >> > [System.Runtime.InteropServices.FieldOffset(0)]
>> >> > public T_B fieldUnion1;
>> >> >
>> >> > [System.Runtime.InteropServices.FieldOffset(0)]
>> >> > public T_C fieldUnion2;
>> >> > }
>> >> >
>> >> >
>> >> > [StructLayout(LayoutKind.Sequential)]
>> >> > public struct T_A{
>> >> >
>> >> > public int fieldA1;
>> >> >
>> >> > public StructUnion fieldA2;
>> >> > }
>> >> >
>> >> >
>> >> >
>> >> > [StructLayout(LayoutKind.Sequential)]
>> >> > public T_MyStruct{
>> >> >
>> >> > [MarshalAs(UnmanagedType.ByValArray,SizeConst = 7)]
>> >> > public T_A[] myField;
>> >> > }
>> >> >
>> >> >
>> >> > [DllImport("mylib.dll", EntryPoint = "MyMethod", SetLastError =
>> >> > true)]
>> >> > public static extern int MyMethod([In,Out] T_MyStruct[]
>> >> > myStructures);
>> >> >
>> >> >
>> >> > The declaration in C languag is equivalent. The only difference is
>> >> > that
>> >> > the
>> >> > fields of structures T_B and T_C are char[100], but I declared
>> >> > them as byte[] in C#. The problem is not coming from this because
>> >> > i've
>> >> > other
>> >> > structures defined like this and working good.
>> >> >
>> >> > The problem is that when I invoke the method I've this error written
>> >> > in
>> >> > the
>> >> > console:
>> >> > "Cannot marshal field 'myField' of type 'T_MyStruct': There is no
>> >> > marshaling
>> >> > support for this type.
>> >> > Failing when marshaling from C# to C.
>> >> >
>> >> > But if I declare the field in structure T_B and T_C as integers the
>> >> > error
>> >> > disapears, failing then internally in the DLL because the
>> >> > types are not correct.
>> >> >
>> >> > Can someone waste some time helping me?
>> >> > This is very imporant to me and I don't know why it's not working.
>> >> >
>> >>
>> >>
>> >>
>>
>>
>>