[Mono-list] marshal a struct
Norbert Lazzeri
elnogge at gmx.de
Fri Oct 3 07:15:18 EDT 2008
seems like you where right. i changed the struct on the c#-side to:
/*****************/
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct INFO
{
public int size;
[MarshalAs(UnmanagedType.ByValArray,SizeConst=100)]
public byte [] data;
public bool flag;
}
/*****************/
also i found a codesnipped on the net:
/*****************/
public static string convertDllData(byte[] mybuffer){
StringBuilder temp = new StringBuilder();
int counter = 0;
for(int i = 0; i < mybuffer.Length; i++){
if(mybuffer[i] != 0x00)
{
temp.Append( Convert.ToChar(mybuffer[i]));
counter++;
}
else{
break;
}
}
return temp.ToString();
}
/*****************/
it does nothing else than adding only those chars to the StringBuilder
that are not null-Characters. using this code everthing works just fine
allthough its very ugly i think..
i also tried to convert the byte-array to a string using
Encoding.ASCII.getString() and some other methods from Encoding but the
problem remains here..
is this a well known bug of monodevelop or should i better file a bug?
best regards,
Norbert
Chris Howie schrieb:
> On Thu, Oct 2, 2008 at 3:54 PM, Norbert Lazzeri <elnogge at gmx.de> wrote:
>
>> im playing around a bit with c# and dllimports.
>>
>> my unmanaged function:
>> /****************************************/
>> struct blub {
>> int size;
>> char data[100];
>> bool flag;
>> };
>> /****************************************/
>> c# - calling code
>> /****************************************/
>> [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
>> public struct INFO
>> {
>> public int size;
>> [MarshalAs(UnmanagedType.ByValArray,SizeConst=100)]
>> public char [] data;
>> public bool flag;
>> }
>>
>> class MainClass
>> {
>>
>> [DllImport ("libmitcode", CharSet = CharSet.Ansi)]
>> private static extern int getStruct(int size, ref INFO str);
>>
>> public static void Main(string[] args)
>> {
>> INFO str = new INFO();
>> int res = getStruct(Marshal.SizeOf(str), ref str);
>>
>> Console.Out.WriteLine(str.size);
>> Console.Out.WriteLine(str.flag);
>> Console.Out.WriteLine("<< " + new String(str.data) + " >>");
>> Console.Out.WriteLine(+ res);
>>
>> }
>> }
>> /****************************************/
>>
>
> A couple of issues:
>
> 1. The C type char and C# type char have different sizes. The
> marshaller is probably going to truncate going from C# to C, and
> coming back it should be filling the array with invalid (that is, not
> unicode) data. Either store a byte[] on the C# class and use
> System.Text.Encoding.ASCII to convert, or use a string, or something.
> Somehow the String constructor or the marshaller is figuring this out
> by itself but I would not rely on this behavior, unless you can find
> where it is documented.
>
> 2. The String(char[]) constructor may not be smart enough to
> understand that a null ASCII character means end-of-string. The
> terminal may be OK ignoring a null character, but the MD output pane
> may not, and that's why you see it truncated there. (This is still
> arguably an MD bug, but you are correct that there are issues with
> your code as well.)
>
>
More information about the Mono-list
mailing list