[Mono-devel-list] Heads up: marshalling changes

RUAUDEL Frédéric ruaudel at embl-grenoble.fr
Tue Sep 7 07:29:50 EDT 2004

Hi Zoltan,

     I have memory allocation problem with one of my mono project. But I 
didn't test it before because I made it with mono 1.0.1 directly. What I 
have is quite strange and could be related to what you are saying, so I 
decided to send it to you. Feel free to skip it if you think it is not 
relevant but any help will be welcome.

I try to map the Net-SNMP library in order to be able to send some snmp 
request to a snmp agent with mono. So to avoid having to map all the 
SNMP structure I made a little wrapper library in C to hide all the 
structure internals. Then I map them using IntPtr data type.

I have a function of the form :

struct foo* get_struct_foo ();

that I map like this :

[DllImport ("my_wrapper_lib")]
private static extern IntPtr get_struct_foo ();

then I have a function that fill that structure :

void fill_struct_foo (struct foo* foo, int value);

that I map :

[DllImport ("my_wrapper_lib")]
private static extern IntPtr  (ref IntPtr foo, int value);

And when I ask the C library to print the value of the pointer, the 
pointer received in the second function is always 0x11 and the program 
finish with a null pointer exception. But I have another structure 
initialized the same way and it works well. Maybe, I made a mistake in 
the marshaling of my parameters, but I tried  almost all the possibility 
and read all msdn doc about it, but nothing has worked.

Here is the instruction to reproduce the problem and the output of my 
test program with the pointer address :

I create it on an FC2 distribution with mono-all.zip of Sep 3rd (V1.0.1)

you must have the following packages installed :

net-snmp 5.1.x (+ devel package)
libelf or elfutils-libelf (+ devel package)

tar zxvf net_snmp_wrapper.tar.gz
cd net_snmp_wrapper
make all test

then start your snmp agent (default config should works) :

service snmpd start  or /etc/init.d/snmpd start

and test the wrapper lib with :

LD_LIBRARY_PATH=. ./test_wrapper public

where "public" is your community string (this is the default one on linux)

the output should be like this :

DEBUG - wsnmp_open(after) : 0x91fffd0
DEBUG - wsnmp_check_opened_session(before) : 0x91fffd0
DEBUG - wsnmp_pdu_create_get(after) : 0x80af590 - 160
DEBUG - wsnmp_add_null_var(before) : 0x80af590 - 0xfef82430 : 1 - 9
DEBUG - wsnmp_add_null_var(before) : 0x80af590 - 0xfef82430 : 1 - 9
DEBUG - wsnmp_add_null_var(before) : 0x80af590 - 0xfef82430 : 1 - 9
Name: . = SNMPv2-MIB::sysDescr.0 - Type : 4 - Value : 
STRING: Linux toto.toto.net 2.6.5-1.358 #1 Sat May 8 09:04:50 EDT 2004 i686
Name: . = SNMPv2-MIB::sysLocation.0 - Type : 4 - Value 
: STRING: "Somewhere"
Name: . = SNMPv2-MIB::sysUpTime.0 - Type : 5 - Value : 
Timeticks: (798) 0:00:07.98

Then compile the mono project

tar zxvf net-snmp-sharp.tar.gz
cd net-snmp-sharp
export LD_LIBRARY_PATH=../net_snmp_wrapper
make -f Makefile.net-snmp-sharp
cp net-snmp-sharp.dll bin/Debug/
cd test
make -f Makefile.net-snmp-test

then execute the test program :

mono net-snmp-test.exe

the output for me is :

Hello World!
DEBUG - wsnmp_open(after) : 0x8fd1ef0
DEBUG - wsnmp_check_opened_session(before) : 0x8fd1ef0
DEBUG - wsnmp_pdu_create_get(after) : 0x9019000 - 160
DEBUG - wsnmp_add_null_var(before) : 0x11 - 0xf675782c : 1 - 9
Unhandled Exception: System.NullReferenceException: Object reference not 
set to an instance of an object
in (unmanaged) (wrapper managed-to-native) NetSnmp:wsnmp_add_null_var 
in <0x00004> (wrapper managed-to-native) NetSnmp:wsnmp_add_null_var 
in <0x0013b> NetSnmp:.ctor (string,string,string)

the problem is that the pointer I retrieve with the function 
wsnmp_pdu_create_get (0x9019000) is lost when I send it to the function 
wsnmp_add_null_var(0x11). If you compare with the output of the C test 
function, you will see that the pointer remain the same (0x80af590). And 
it works well for the function wsnmp_open, the pointer remain the same 
in the function wsnmp_check_opened_session (0x8fd1ef0)

the function declaration are the following :

C:     netsnmp_pdu* wsnmp_pdu_create_get (void);
C#:   private static extern IntPtr wsnmp_pdu_create_get ();

C:     netsnmp_variable_list* wsnmp_add_null_var (netsnmp_pdu* pdu, 
const oid* objid, size_t objid_len);
C#:   private static extern IntPtr wsnmp_add_null_var (ref IntPtr pdu, 
ref long[] objid, int objid_len);

If you need more information, feel free to ask,

Thanks in advance for any help on this,


Zoltan Varga wrote:

>                                            Hi,
>  I checked in some major changes to mono's marshalling infrastructure primary
>to fix some memory leaks with the old code. There is a high probability that 
>some things were broken in the process. So if you have some pinvoke code which
>used to work but doesn't work now, drop a mail to the list, and I will
>look into it.
>                                                         Zoltan
>Mono-devel-list mailing list
>Mono-devel-list at lists.ximian.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: net-snmp-sharp.tar.gz
Type: application/x-gzip
Size: 8055 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20040907/feff090b/attachment.gz 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: net_snmp_wrapper.tar.gz
Type: application/x-gzip
Size: 3613 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20040907/feff090b/attachment-0001.gz 

More information about the Mono-devel-list mailing list