@@ -22,7 +22,10 @@ class {{ callback_impl_name }} {
2222
2323 { % - match meth . return_type( ) % }
2424 { % - when Some with ( return_type ) % }
25- @uniffiOutReturn = { { return_type | ffi_converter_name } } . INSTANCE . Lower ( result ) ;
25+ unsafe {
26+ { % - let return_ffi_type = return_type| ffi_type % }
27+ * ( { { return_ffi_type | ffi_type_name } } * ) uniffiOutReturn = { { return_type | ffi_converter_name } } . INSTANCE . Lower ( result ) ;
28+ }
2629 { % - when None % }
2730 { % - endmatch % }
2831
@@ -109,8 +112,10 @@ class {{ callback_impl_name }} {
109112 } , cts . Token ) ;
110113
111114 var foreignHandle = _UniFFIAsync. _foreign_futures_map . Insert ( cts ) ;
112- @uniffiOutReturn . @handle = foreignHandle ;
113- @uniffiOutReturn . @free = Marshal . GetFunctionPointerForDelegate ( _UniFFIAsync . UniffiForeignFutureFreeCallback . callback ) ;
115+ unsafe {
116+ ( * ( _UniFFILib . UniffiForeignFuture * ) uniffiOutReturn ) . handle = foreignHandle ;
117+ ( * ( _UniFFILib . UniffiForeignFuture * ) uniffiOutReturn ) . free = Marshal . GetFunctionPointerForDelegate ( _UniFFIAsync . UniffiForeignFutureFreeCallback . callback ) ; ;
118+ }
114119 { % - endif % }
115120 } else {
116121 throw new InternalException ( $ "No callback in handlemap '{ handle } '") ;
@@ -128,16 +133,17 @@ static void UniffiFree(ulong @handle) {
128133 { % - endfor % }
129134 static _UniFFILib . UniffiCallbackInterfaceFree _callback_interface_free = new _UniFFILib . UniffiCallbackInterfaceFree ( UniffiFree ) ;
130135
131- public static _UniFFILib . { { vtable | ffi_type_name } } _vtable = new _UniFFILib . { { vtable | ffi_type_name } } {
132- { % - for ( ffi_callback , meth ) in vtable_methods. iter ( ) % }
133- { % - let fn_type = format! ( "_UniFFILib.{}Method" , callback_impl_name ) % }
134- { { meth . name ( ) | var_name ( ) } } = Marshal . GetFunctionPointerForDelegate ( _m { { loop . index0 } } ) ,
135- { % - endfor % }
136- @uniffiFree = Marshal . GetFunctionPointerForDelegate ( _callback_interface_free )
137- } ;
138-
139136 public static void Register ( ) {
140- _UniFFILib . { { ffi_init_callback . name ( ) } } ( ref { { callback_impl_name } } . _vtable ) ;
137+ _UniFFILib . { { vtable | ffi_type_name } } _vtable = new _UniFFILib . { { vtable | ffi_type_name } } {
138+ { % - for ( ffi_callback , meth ) in vtable_methods . iter ( ) % }
139+ { % - let fn_type = format! ( "_UniFFILib.{}Method" , callback_impl_name ) % }
140+ { { meth . name ( ) | var_name ( ) } } = Marshal . GetFunctionPointerForDelegate ( _m { { loop . index0 } } ) ,
141+ { % - endfor % }
142+ @uniffiFree = Marshal . GetFunctionPointerForDelegate ( _callback_interface_free )
143+ } ;
144+
145+ // Pin vtable to ensure GC does not move the vtable across the heap
146+ _UniFFILib . { { ffi_init_callback . name ( ) } } ( GCHandle . Alloc ( _vtable , GCHandleType . Pinned ) . AddrOfPinnedObject ( ) ) ;
141147 }
142148}
143149
0 commit comments