[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

microsoft.public.dotnet.framework.interop

How to marshal complex data structures

James Whetstone

2/5/2007 4:14:00 AM

Hi,

I'm using Pinvoke and C# interop to interface to a C DLL. The DLL function
signiture is as follows:

int fun(char *name, my_id_t *id, my_buffer_t *buffer);


The user defined types (in C) are as follows:


struct my_id_t
{
unsigned char guid[16];
}

struct my_subbuffer_t
{
int format;
}

struct my_buffer_t
{
int count;
my_subbuffer_t **bufferArray;
}

So I'm having trouble with the 3rd argument---my_buffer_t.

This is what I've got so far in C#:

[StructLayout(LayoutKind.Sequential)]
public class my_id_t
{
[MarshalAs(UnManagedType.ByValArray, SizeConst=16)]
public byte[] myGuid;
}

[StructLayout(LayoutKind.Sequential)]
public class my_subbuffer_t
{
public int format;
}

[StructLayout(LayoutKind.Sequential)]
public class my_buffer_t
{
public int count;
my_subbuffer_t [] buffers;
}




35 Answers

James Whetstone

2/5/2007 4:19:00 AM

0

Oops, forgot to add the pinvoke signiture:

[DllImport("mylib.dll")]

public static extern int fun(string name, my_id_t id, my_buffer_t buffer);

So when I run my code, the buffer is corrupted/invalid memory.

Can you guys help out with some code or point my in the right direction?

Thanks!
JW


"James Whetstone" <jameswhetstone@comcast.net> wrote in message
news:t7WdnSN0HqWVMlvYnZ2dnUVZ_qqrnZ2d@comcast.com...
> Hi,
>
> I'm using Pinvoke and C# interop to interface to a C DLL. The DLL
> function signiture is as follows:
>
> int fun(char *name, my_id_t *id, my_buffer_t *buffer);
>
>
> The user defined types (in C) are as follows:
>
>
> struct my_id_t
> {
> unsigned char guid[16];
> }
>
> struct my_subbuffer_t
> {
> int format;
> }
>
> struct my_buffer_t
> {
> int count;
> my_subbuffer_t **bufferArray;
> }
>
> So I'm having trouble with the 3rd argument---my_buffer_t.
>
> This is what I've got so far in C#:
>
> [StructLayout(LayoutKind.Sequential)]
> public class my_id_t
> {
> [MarshalAs(UnManagedType.ByValArray, SizeConst=16)]
> public byte[] myGuid;
> }
>
> [StructLayout(LayoutKind.Sequential)]
> public class my_subbuffer_t
> {
> public int format;
> }
>
> [StructLayout(LayoutKind.Sequential)]
> public class my_buffer_t
> {
> public int count;
> my_subbuffer_t [] buffers;
> }
>
>
>
>


TDC

2/5/2007 2:27:00 PM

0

I think the fact that you are using formatted classes instead of
structs in your code require you to flag the parameter with the
InAttribute and OutAttribute ( [In, Out] ). Otherwise it would
default to In only.



On Feb 4, 11:18 pm, "James Whetstone" <jameswhetst...@comcast.net>
wrote:
> Oops, forgot to add the pinvoke signiture:
>
> [DllImport("mylib.dll")]
>
> public static extern int fun(string name, my_id_t id, my_buffer_t buffer);
>
> So when I run my code, the buffer is corrupted/invalid memory.
>
> Can you guys help out with some code or point my in the right direction?
>
> Thanks!
> JW
>
> "James Whetstone" <jameswhetst...@comcast.net> wrote in message
>
> news:t7WdnSN0HqWVMlvYnZ2dnUVZ_qqrnZ2d@comcast.com...
>
>
>
> > Hi,
>
> > I'm using Pinvoke and C# interop to interface to a C DLL. The DLL
> > function signiture is as follows:
>
> > int fun(char *name, my_id_t *id, my_buffer_t *buffer);
>
> > The user defined types (in C) are as follows:
>
> > struct my_id_t
> > {
> > unsigned char guid[16];
> > }
>
> > struct my_subbuffer_t
> > {
> > int format;
> > }
>
> > struct my_buffer_t
> > {
> > int count;
> > my_subbuffer_t **bufferArray;
> > }
>
> > So I'm having trouble with the 3rd argument---my_buffer_t.
>
> > This is what I've got so far in C#:
>
> > [StructLayout(LayoutKind.Sequential)]
> > public class my_id_t
> > {
> > [MarshalAs(UnManagedType.ByValArray, SizeConst=16)]
> > public byte[] myGuid;
> > }
>
> > [StructLayout(LayoutKind.Sequential)]
> > public class my_subbuffer_t
> > {
> > public int format;
> > }
>
> > [StructLayout(LayoutKind.Sequential)]
> > public class my_buffer_t
> > {
> > public int count;
> > my_subbuffer_t [] buffers;
> > }- Hide quoted text -
>
> - Show quoted text -


James Whetstone

2/5/2007 9:22:00 PM

0

Thanks for the suggestion. I just tried it by adding

[In, Out] to the parameter on the Pinvoke siginiture. So it looked like
this:

public static extern int fun(string name, my_id_t id, [In,Out]my_buffer_t
buffer);

I also changed the class to a struct and changed the pinvoke signiture to
this:

public static extern int fun(string name, my_id_t id, [In,Out] ref
my_buffer_t buffer);

But that didn't work either. Any other thoughts or comments?

Cheers,
JW

"TDC" <NOtcarvinSPAM@lycos.com> wrote in message
news:1170685614.384106.283150@h3g2000cwc.googlegroups.com...
>I think the fact that you are using formatted classes instead of
> structs in your code require you to flag the parameter with the
> InAttribute and OutAttribute ( [In, Out] ). Otherwise it would
> default to In only.
>
>
>
> On Feb 4, 11:18 pm, "James Whetstone" <jameswhetst...@comcast.net>
> wrote:
>> Oops, forgot to add the pinvoke signiture:
>>
>> [DllImport("mylib.dll")]
>>
>> public static extern int fun(string name, my_id_t id, my_buffer_t
>> buffer);
>>
>> So when I run my code, the buffer is corrupted/invalid memory.
>>
>> Can you guys help out with some code or point my in the right direction?
>>
>> Thanks!
>> JW
>>
>> "James Whetstone" <jameswhetst...@comcast.net> wrote in message
>>
>> news:t7WdnSN0HqWVMlvYnZ2dnUVZ_qqrnZ2d@comcast.com...
>>
>>
>>
>> > Hi,
>>
>> > I'm using Pinvoke and C# interop to interface to a C DLL. The DLL
>> > function signiture is as follows:
>>
>> > int fun(char *name, my_id_t *id, my_buffer_t *buffer);
>>
>> > The user defined types (in C) are as follows:
>>
>> > struct my_id_t
>> > {
>> > unsigned char guid[16];
>> > }
>>
>> > struct my_subbuffer_t
>> > {
>> > int format;
>> > }
>>
>> > struct my_buffer_t
>> > {
>> > int count;
>> > my_subbuffer_t **bufferArray;
>> > }
>>
>> > So I'm having trouble with the 3rd argument---my_buffer_t.
>>
>> > This is what I've got so far in C#:
>>
>> > [StructLayout(LayoutKind.Sequential)]
>> > public class my_id_t
>> > {
>> > [MarshalAs(UnManagedType.ByValArray, SizeConst=16)]
>> > public byte[] myGuid;
>> > }
>>
>> > [StructLayout(LayoutKind.Sequential)]
>> > public class my_subbuffer_t
>> > {
>> > public int format;
>> > }
>>
>> > [StructLayout(LayoutKind.Sequential)]
>> > public class my_buffer_t
>> > {
>> > public int count;
>> > my_subbuffer_t [] buffers;
>> > }- Hide quoted text -
>>
>> - Show quoted text -
>
>


Michael Phillips, Jr.

2/5/2007 9:58:00 PM

0

> public static extern int fun(string name, my_id_t id, [In,Out] ref
> my_buffer_t buffer);

The above should work. How did you allocate memory for buffer?

Did you allocate memory for my_buffer_t and the array my_subbuffer_t?

If so, you may want to try to lay out your structs explicitely rather than
sequentially to avoid implicit packing alignment issues of struct members.


James Whetstone

2/6/2007 5:27:00 AM

0


So I'm allocating memory for my_buffer_t like this:

my_buffer_t buf = new my_buffer_t();
buf.count = 1;

buf.buffers = new my_subbuffer_t[1];

buf.buffers[0].format = 100;

Does this look right? I don't need to allocate on the unmanaged heap,
right?

I'll try using an explicit layout. Thanks for the suggestions.

JW


"Michael Phillips, Jr." <mphillips53@nospam.jun0.c0m> wrote in message
news:%23W65BDXSHHA.4404@TK2MSFTNGP03.phx.gbl...
>> public static extern int fun(string name, my_id_t id, [In,Out] ref
>> my_buffer_t buffer);
>
> The above should work. How did you allocate memory for buffer?
>
> Did you allocate memory for my_buffer_t and the array my_subbuffer_t?
>
> If so, you may want to try to lay out your structs explicitely rather than
> sequentially to avoid implicit packing alignment issues of struct members.
>


James Whetstone

2/6/2007 6:46:00 AM

0

Okay,

So this is what I've got implemented now:


[StructLayout(LayoutKind.Sequential)]
public class my_subbuffer_t
{
public int format;
}

[StructLayout(LayoutKind.Sequential)]
public class my_buffer_t
{
public int count;
public my_subbuffer_t [] buffers;
}

[DllImport("mylib.dll")]
public static extern int fun(string name, my_id_t id, [In, Out] ref
my_buffer_t buffer);

my_buffer_t buf;

buf.buffers = new my_subbuffers_t[1];
buf.buffers[0].format = 100;
buf.count=1;

string name="Jimbo";
my_id_t id = new my_id_t();

fun(name,id,ref buf);

So now I get the following runtime error:
Invalid managed/unmanaged type combination (this value type must be paired
with Struct).

Best,
JW








"Michael Phillips, Jr." <mphillips53@nospam.jun0.c0m> wrote in message
news:%23W65BDXSHHA.4404@TK2MSFTNGP03.phx.gbl...
>> public static extern int fun(string name, my_id_t id, [In,Out] ref
>> my_buffer_t buffer);
>
> The above should work. How did you allocate memory for buffer?
>
> Did you allocate memory for my_buffer_t and the array my_subbuffer_t?
>
> If so, you may want to try to lay out your structs explicitely rather than
> sequentially to avoid implicit packing alignment issues of struct members.
>


James Whetstone

2/6/2007 6:48:00 AM

0

Sorry,

that wasn't quite right...I've changed the "classes" to "structs" like so:

[StructLayout(LayoutKind.Sequential)]
public struct my_subbuffer_t
{
public int format;
}
[StructLayout(LayoutKind.Sequential)]
public class my_buffer_t
{
public int count;
public my_subbuffer_t [] buffers;
}

....

Thanks for takin' the time,
JW


"James Whetstone" <jameswhetstone@comcast.net> wrote in message
news:TqudnZ9izd2ouVXYnZ2dnUVZ_v-tnZ2d@comcast.com...
> Okay,
>
> So this is what I've got implemented now:
>
>
> [StructLayout(LayoutKind.Sequential)]
> public class my_subbuffer_t
> {
> public int format;
> }
>
> [StructLayout(LayoutKind.Sequential)]
> public class my_buffer_t
> {
> public int count;
> public my_subbuffer_t [] buffers;
> }
>
> [DllImport("mylib.dll")]
> public static extern int fun(string name, my_id_t id, [In, Out] ref
> my_buffer_t buffer);
>
> my_buffer_t buf;
>
> buf.buffers = new my_subbuffers_t[1];
> buf.buffers[0].format = 100;
> buf.count=1;
>
> string name="Jimbo";
> my_id_t id = new my_id_t();
>
> fun(name,id,ref buf);
>
> So now I get the following runtime error:
> Invalid managed/unmanaged type combination (this value type must be paired
> with Struct).
>
> Best,
> JW
>
>
>
>
>
>
>
>
> "Michael Phillips, Jr." <mphillips53@nospam.jun0.c0m> wrote in message
> news:%23W65BDXSHHA.4404@TK2MSFTNGP03.phx.gbl...
>>> public static extern int fun(string name, my_id_t id, [In,Out] ref
>>> my_buffer_t buffer);
>>
>> The above should work. How did you allocate memory for buffer?
>>
>> Did you allocate memory for my_buffer_t and the array my_subbuffer_t?
>>
>> If so, you may want to try to lay out your structs explicitely rather
>> than sequentially to avoid implicit packing alignment issues of struct
>> members.
>>
>
>


James Whetstone

2/6/2007 6:50:00 AM

0

So to clarify, all my classes are now structs.
Thanks,
JW

"James Whetstone" <jameswhetstone@comcast.net> wrote in message
news:ZLSdnc1YYIQmuVXYnZ2dnUVZ_revnZ2d@comcast.com...
> Sorry,
>
> that wasn't quite right...I've changed the "classes" to "structs" like so:
>
> [StructLayout(LayoutKind.Sequential)]
> public struct my_subbuffer_t
> {
> public int format;
> }
> [StructLayout(LayoutKind.Sequential)]
> public class my_buffer_t
> {
> public int count;
> public my_subbuffer_t [] buffers;
> }
>
> ...
>
> Thanks for takin' the time,
> JW
>
>
> "James Whetstone" <jameswhetstone@comcast.net> wrote in message
> news:TqudnZ9izd2ouVXYnZ2dnUVZ_v-tnZ2d@comcast.com...
>> Okay,
>>
>> So this is what I've got implemented now:
>>
>>
>> [StructLayout(LayoutKind.Sequential)]
>> public class my_subbuffer_t
>> {
>> public int format;
>> }
>>
>> [StructLayout(LayoutKind.Sequential)]
>> public class my_buffer_t
>> {
>> public int count;
>> public my_subbuffer_t [] buffers;
>> }
>>
>> [DllImport("mylib.dll")]
>> public static extern int fun(string name, my_id_t id, [In, Out] ref
>> my_buffer_t buffer);
>>
>> my_buffer_t buf;
>>
>> buf.buffers = new my_subbuffers_t[1];
>> buf.buffers[0].format = 100;
>> buf.count=1;
>>
>> string name="Jimbo";
>> my_id_t id = new my_id_t();
>>
>> fun(name,id,ref buf);
>>
>> So now I get the following runtime error:
>> Invalid managed/unmanaged type combination (this value type must be
>> paired with Struct).
>>
>> Best,
>> JW
>>
>>
>>
>>
>>
>>
>>
>>
>> "Michael Phillips, Jr." <mphillips53@nospam.jun0.c0m> wrote in message
>> news:%23W65BDXSHHA.4404@TK2MSFTNGP03.phx.gbl...
>>>> public static extern int fun(string name, my_id_t id, [In,Out] ref
>>>> my_buffer_t buffer);
>>>
>>> The above should work. How did you allocate memory for buffer?
>>>
>>> Did you allocate memory for my_buffer_t and the array my_subbuffer_t?
>>>
>>> If so, you may want to try to lay out your structs explicitely rather
>>> than sequentially to avoid implicit packing alignment issues of struct
>>> members.
>>>
>>
>>
>
>


Michael Phillips, Jr.

2/6/2007 2:53:00 PM

0

Do you now get the expected result(i.e., no interop errors)?



James Whetstone

2/6/2007 4:45:00 PM

0

No. I'm getting the following runtime error:

Invalid managed/unmanaged type combination (this value type must be paired
with Struct).


"Michael Phillips, Jr." <mphillips53@nospam.jun0.c0m> wrote in message
news:eNSpx5fSHHA.3500@TK2MSFTNGP05.phx.gbl...
> Do you now get the expected result(i.e., no interop errors)?
>
>
>