11use std:: sync:: Arc ;
22use crate :: error:: FFIResult ;
33
4- use crate :: handle:: { Out , Ref , HandleShared } ;
5-
6- /// Lower level items for debugging wrapper library.
7- /// When the FFI crashes without error messages, testing with these might be useful to understand
8- /// what is the exact cause of the crash.
9-
104/// These tests should be used for asserting that the wrapper code can see the expected
115/// error messages when it fails (or succeeds).
126ffi ! {
@@ -21,92 +15,3 @@ ffi! {
2115 }
2216}
2317
24-
25- #[ repr( C ) ]
26- pub struct FFITestInputStructWithPtr {
27- fn_ptr : extern "cdecl" fn ( * const Self ) ,
28- }
29- impl FFITestInputStructWithPtr {
30- pub fn call ( & self ) {
31- ( self . fn_ptr ) ( self as * const _ )
32- }
33- }
34-
35- pub struct FFITestOutputStruct {
36- field : Arc < FFITestInputStructWithPtr >
37- }
38-
39- impl FFITestOutputStruct {
40- fn complete ( & self ) {
41- println ! ( "finished!" ) ;
42- self . field . call ( ) ;
43- }
44- }
45-
46- type FFITestOutputStructHandle < ' a > = HandleShared < ' a , FFITestOutputStruct > ;
47-
48- type FFIFunctionPointer = extern "cdecl" fn ( input : * const FFITestInputStructWithPtr ) ;
49- type FFIFunctionPointerWithReturn = extern "cdecl" fn ( input : i32 ) -> i32 ;
50- type FFIFunctionPointerWithReturnRef = extern "cdecl" fn ( input : * const i32 ) -> * const i32 ;
51-
52- ffi ! {
53- fn ffi_test_function_ptr( struct_arg_ptr: Ref <FFITestInputStructWithPtr >, fn_ptr: Ref <FFIFunctionPointer >) -> FFIResult {
54- // verify that if we pass functoin pointer and wrapper object separately and only calls the formar, it works.
55- let func = unsafe_block!( "" => fn_ptr. as_ref( ) ) ;
56- let struct_arg = unsafe_block!( "" => struct_arg_ptr. as_ref( ) ) ;
57- ( func) ( struct_arg) ;
58- FFIResult :: ok( )
59- }
60-
61- fn ffi_simple_nested_struct( input: Ref <FFIFunctionPointer >, output: Out <FFITestOutputStructHandle >) -> FFIResult {
62- // verify that function pointer can be a member of other object.
63- let input_ref = unsafe_block!( " " => input. as_ref( ) ) ;
64- let result = FFITestOutputStruct { field: Arc :: new( FFITestInputStructWithPtr { fn_ptr: * input_ref } ) } ;
65- result. complete( ) ;
66- unsafe_block!( "" => output. init( HandleShared :: alloc( result) ) ) ;
67- FFIResult :: ok( )
68- }
69-
70- fn ffi_simple_nested_struct_with_return_value( val_return_fn: Ref <FFIFunctionPointerWithReturn >, ref_return_fn: Ref <FFIFunctionPointerWithReturnRef >) -> FFIResult {
71- // verify that functoin pointer can return value. and it could be seen in wrapper lang side.
72- let val_return_fn_ref = unsafe_block!( "" => val_return_fn. as_ref( ) ) ;
73- let ref_return_fn_ref = unsafe_block!( "" => ref_return_fn. as_ref( ) ) ;
74-
75- let val = ( val_return_fn_ref) ( 33 ) ;
76- let r_ptr = ( ref_return_fn_ref) ( & 44 ) ;
77- let r = unsafe_block!( "" => * r_ptr) ;
78- println!( "val was {}" , val) ;
79- println!( "ref was {}" , r) ;
80-
81- let val2 = ( val_return_fn_ref) ( 66 ) ;
82- let r_ptr2 = ( ref_return_fn_ref) ( & 88 ) ;
83- let r2 = unsafe_block!( "" => * r_ptr2) ;
84- println!( "val2 was {}" , val2) ;
85- println!( "ref2 was {}" , r2) ;
86- FFIResult :: ok( )
87- }
88-
89- fn ffi_test_simple_struct_with_function_pointer(
90- input: Ref <FFITestInputStructWithPtr >,
91- output: Out <FFITestOutputStructHandle >
92- ) -> FFIResult {
93- // this test does not work, it seems that calling a function passed by wrapper struct will cause program to crash.
94- let input_ref = unsafe_block!( " " => input. as_ref( ) ) ;
95- // input_ref.call();
96- let input_arc = unsafe_block!( " " => input. as_arc( ) ) ;
97- // input_arc.call();
98- // let result = FFITestOutputStruct{ field: input_arc };
99- // result.field.call();
100- // unsafe_block!("We know output is not null by wrapper macro. And we know `Out` is writable" => output.init(HandleShared::alloc(result)));
101- FFIResult :: ok( )
102- }
103-
104- fn ffi_test_release( handle: FFITestOutputStructHandle ) -> FFIResult {
105- unsafe_block!( "The upstream caller guarantees the handle will not be accessed after being freed" => FFITestOutputStructHandle :: dealloc( handle, |mut handle| {
106- handle. complete( ) ;
107-
108- FFIResult :: ok( )
109- } ) )
110- }
111-
112- }
0 commit comments