[Mono-list] Support for Marshal.PtrToStructure in mono?
Kala B
kalabalun@yahoo.co.in
Tue, 4 Jan 2005 13:48:27 +0000 (GMT)
Hi,
mono supports Marshal.PtrToStructure when the
structure has a char[] with Charset = Unicode, but
does not support a string!!
For example, the following works perfectly fine in
mono without throwing any errors.
[StructLayout(LayoutKind.Sequential, CharSet =
CharSet.Unicode)]
public class Id
{
public int id;
[MarshalAs(UnmanagedType.ByValArray, SizeConst =
128)]
public char[] name;
};
Is there any specific reason/ major difference for
mono supporting char[] with Marshal.PtrToStructure and
not adding supporting String?
Thanks and Regards
Kala B.
--- Kala B <kalabalun@yahoo.co.in> wrote:
> Hi Jon,
> Thanks a lot for your reply. Sorry for the delayed
> response. Was away on vacation.
>
> I tried my code on mono 1.1.3. With that too I get
> the
> same error:
>
-------------------------------------------------------
> ** (./mytest.exe:8693): WARNING **: marshaling
> conversion 12 not implemented
>
> ** ERROR **: file marshal.c: line 987
> (emit_ptr_to_str_conv): should not be reached
> aborting...
> Abort
>
>
-------------------------------------------------------
> The only difference between mono 1.0.4 ( the one I
> use) to mono 1.1.3 is that, in mono 1.0.4 I get this
> error, only when the execution path reaches the
> Marshal.PtrToStructure code path. In mono 1.1.3, the
> error is thrown the moment I run the exe.
>
> Looks like, Marshal.PtrToStructure does not work
> when
> the structure contains a wchar_t ( Charset = Unicode
> and the string is marshalled as
> UnmanagedType.ByValTStr). I have pasted my sample
> code. When I tried the same with Charset = Ansi and
> char on the C side, everything worked fine.
>
> Sample code:
> ------------
> Contents of test.c
> ------------------
>
> #include <stdio.h>
> #include <wchar.h>
> #include <assert.h>
> typedef struct _id
> {
> int id;
> // char name[128];
> wchar_t name[128];
> }Id;
>
> typedef struct _idlist
> {
> int num;
> Id *list;
> }IdList;
>
> int myfunc(IdList *idList)
> {
> printf("In lib : %s \t idList->num is
> %d\n",__func__,idList->num);
> assert(idList->list);
> idList->list[0].id = 10;
> // strcpy(idList->list[0].name,"One");
> wcscpy(idList->list[0].name,L"One");
> idList->list[1].id = 20;
> // strcpy(idList->list[1].name,"Two");
> wcscpy(idList->list[1].name,L"Two");
> idList->num = 2;
> return 1;
> }
>
> Contents of chash.cs
> --------------------
> using System;
> using System.Runtime.InteropServices;
> using System.Text;
> using System.Collections.Specialized;
>
> [StructLayout(LayoutKind.Sequential, CharSet =
> CharSet.Unicode)]
> //[StructLayout(LayoutKind.Sequential, CharSet =
> CharSet.Ansi)]
> public class Id
> {
> public int id;
> [MarshalAs(UnmanagedType.ByValTStr, SizeConst =
> 128)]
> public string name;
> };
>
> [StructLayout(LayoutKind.Sequential, CharSet =
> CharSet.Unicode)]
> //[StructLayout(LayoutKind.Sequential, CharSet =
> CharSet.Ansi)]
>
> public class IdList
> {
> public int num;
> public IntPtr list;
> };
>
> class Test
> {
> [DllImport("libtest.so")]
> public static extern int myfunc([In, Out] IdList
> idList);
>
> public static void Main()
> {
> Id id = new Id();
> IdList idList = new IdList();
> //Allocate memory for 3 ids.
> idList.num = 3;
> idList.list = Marshal.AllocHGlobal(3 *
> Marshal.SizeOf(id));
>
> int rcode = myfunc(idList);
> Console.WriteLine("\nmyfunc returns {0} and
> numids returned is {1} ",rcode,idList.num);
> for (int i = 0; i< idList.num; i++)
> {
> IntPtr temp = new
> IntPtr(idList.list.ToInt32() + (i *
> Marshal.SizeOf(id)));
> id = (Id)Marshal.PtrToStructure(temp,
> typeof(Id));
> Console.WriteLine("idList[{0}] is {1}
> {2}",i,id.id,id.name);
> }
> Marshal.FreeHGlobal(idList.list);
>
> }
> }
>
>
> Contents of makefile
> ---------------------
> all: lib test
> lib: testlib.c
> gcc -fPIC -g -c test.c
> ld -x --shared -o libtest.so test.o
> test:
> mcs -debug chash.cs
> clean :
> rm ./libtest.so
>
>
>
> The above sample code would anyway not print the
> correct strings because of wide character issues
> between mono and Linux wchar_t.
>
> But MarshalAs(UnmanagedType.ByValTStr) with
> Charset=Unicode works fine if I donot use this
> structure with Marshal.PtrToStructure. ( with some
> changes for handling the wchar_t issues).
>
> There is no difference in behaviour between mono
> 1.0.4
> and mono 1.1.3 for the sample code.
>
> Would this be supported in mono? Is there any
> alternative solution for this problem?
>
> Thanks in advance.
> Regards
> Kala B.
>
>
>
>
>
>
>
>
>
>
>
>
>
> --- Jonathan Pryor <jonpryor@vt.edu> wrote:
> > On Thu, 2004-12-23 at 10:09 +0000, Kala B wrote:
> > > Does mono provide support for
> > Marshal.PtrToStructure?
> >
> > Yes, and No. :-)
> >
> > Yes, Marshal.PtrToStructure is supported, but
> > apparently it's not
> > *fully* supported. I imagine the nested pointer
> to
> > an array of structs
> > isn't implemented by mono's marshaller.
> >
> > Could you create a small test case and add it to
> > bugzilla.ximian.com?
> > The bug should be added to "Mono: Runtime".
> >
> > Also, which version of Mono are you using? It's
> > possible that Mono
> > 1.1.3 (the development branch) has fixed this
> > problem; it might be worth
> > testing your program under it.
> >
> > Thanks,
>
=== message truncated ===
________________________________________________________________________
Yahoo! India Matrimony: Find your life partner online
Go to: http://yahoo.shaadi.com/india-matrimony