[Mono-list] Embedded API. Numeric Boxing and GC

Robert Jordan robertj at gmx.net
Tue Feb 25 12:18:04 UTC 2014


On 25.02.2014 11:20, jonathan at mugginsoft.com wrote:
> I box my numeric primitives using a macro:
>
> #define DB_BOX_INT64( x ) ( mono_value_box(mono_domain_get(), mono_get_int64_class(), &x) )
>
>
> And use it like so:
>
> 1.
>
> - (void)box
> {
> MonoObject *monoObject = DB_BOX_INT64(value);
> }
>
> I save the MonoObject * into a local variable. The collector will see the object on the stack and collect it only when the enclosing function completes.
>
> 2.
> - (void)box:(long long)value
> {
> 	self.monoObject = DB_BOX_INT64(value);
> 	self.gcHandle = mono_gchandle_new(self.monoObject, FALSE);
> }
>
> - (void)dealloc
> {
> 	mono_gchandle_free(self.gcHandle);
> }
>
> I save the MonoObject * into an instance variable. The collector will free the MonoObject after the call to mono_gchandle_free().
>
> Is the above correct?

Not quite. Look at this line:

self.monoObject = DB_BOX_INT64(value);

There is a chance that the MonoObject* remains only reachable
from self.monoObject. This means that it might be GCed before
a handle could be taken from it.

Something along these lines should be safe:

MonoObject *obj = DB_BOX_INT64(value);
self.gcHandle = mono_gchandle_new(obj, FALSE);
self.monoObject = obj;


For the paranoid:

self.gcHandle = mono_gchandle_new(DB_BOX_INT64(value), FALSE);
self.monoObject = mono_gchandle_get_target(self.gcHandle);

:)

Robert




More information about the Mono-list mailing list