[Mono-list] Support for Marshal.PtrToStructure in mono?

Kala B kalabalun@yahoo.co.in
Mon, 3 Jan 2005 13:03:47 +0000 (GMT)


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,
>  - Jon
> 
> 
> 
> _______________________________________________
> Mono-list maillist  -  Mono-list@lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-list
>  

________________________________________________________________________
Yahoo! India Matrimony: Find your life partner online
Go to: http://yahoo.shaadi.com/india-matrimony