all groups > dotnet interop > march 2005 >
You're in the

dotnet interop

group:

PInvoke marshaling a char* inside a struct



PInvoke marshaling a char* inside a struct deleria010
3/17/2005 8:01:19 AM
dotnet interop: I have a C struct that contains a char* and I am tring to use PInvoke
(and C#) to marshal it as a string but it is not working. I was hoping
someone has done something like this and will give me a hint on how to
get it to work. I also have to add a uchar* that points to the start
of a large uchar array. I don't know what C# type this should be
marshaled as.

Something odd is happening when the char* was added. After calling
takeStruct, the C#'s variable members were not set but after calling
returnStruct, the variable members were set correctly!! Why would the
char* be breaking the marshaling of the reset of the members.

Here is the code so far:

..h

struct myStruct {
ushort c1;
uchar c2;
uchar c3;
uchar c4;
uchar c5;
uchar c6;
uchar c7;
bool c8;
char* c9;
};
struct myStruct* st;

void takeStruct(struct myStruct* s);
struct myStruct* returnStruct();


..cc

extern "C" void takeStruct(struct myStruct* s)
{
s->c1 = 1;
s->c2 = 2;
s->c3 = 3;
s->c4 = 4;
s->c5 = 5;
s->c6 = 6;
s->c7 = 7;
s->c8 = true;
s->c9 = "hello";
}

struct myStruct* returnStruct()
{
if (st == 0) {
st = new struct myStruct;
}
st->c1 = 1;
st->c2 = 2;
st->c3 = 3;
st->c4 = 4;
st->c5 = 5;
st->c6 = 6;
st->c7 = 7;
st->c8 = true;
st->c9 = "world";

return st;
}


C#

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=4)]
public class MyStruct
{
public ushort cs1;
public byte cs2;
public byte cs3;
public byte cs4;
public byte cs5;
public byte cs6;
public byte cs7;
public bool cs8;
[MarshalAs(UnmanagedType.LPStr)]
public string cs9;
}

[DllImport("ctisr_csharp.dll")]
public static extern void
takeStruct([MarshalAs(UnmanagedType.LPStruct)] MyStruct c);

[DllImport("ctisr_csharp.dll")]
[return : MarshalAs(UnmanagedType.LPStruct)]
public static extern MyStruct returnStruct();


Thanks for reading
Re: PInvoke marshaling a char* inside a struct Mattias Sjögren
3/18/2005 12:37:33 PM

[quoted text, click to view]


Adding the string member makes the type non-blittable and it requires
marshaling. For a class that only happens in one direction by default,
and you have to add the [In, Out] attributes to ensure that any
changes are copied back.



Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
AddThis Social Bookmark Button