11include (joinpath (@__DIR__ , " testcommon.jl" ))
22
3+ GC. enable (true )
4+
35# Wrap the functions defined in C++
46module CppInheritance
57
2527
2628using . CppInheritance
2729
30+ # Normal Julia callback
31+ function double (x:: Float64 )
32+ return 2 x
33+ end
34+
35+ # callback as a C function
36+ c_double = @safe_cfunction (double, Float64, (Float64,))
37+
38+ # Base class for extended classes in Julia
39+ abstract type AbstractJuliaExtended <: CppInheritance.VirtualCpp end
40+ # Every C++ function called on the Julia extended classes needs this kind of specialization
41+ CppInheritance. virtualfunc (x:: AbstractJuliaExtended ) = CppInheritance. virtualfunc (x. referred_object)
42+
43+ function make_callback (firstval_ref)
44+ cb (x:: Float64 ) = 2 x + firstval_ref[]
45+ cb_noclosure (x:: Float64 ) = 3 x
46+ try
47+ return @safe_cfunction ($ cb, Float64, (Float64,))
48+ catch e
49+ @warn " Creating cfunction failed with error $e "
50+ return @safe_cfunction ($ cb_noclosure, Float64, (Float64,))
51+ end
52+ end
53+
54+ # Example of an extension implemented in Julia
55+ struct JuliaExtended <: AbstractJuliaExtended
56+ function JuliaExtended (len, value)
57+ ref_obj = CppInheritance. VirtualCfunctionExtended (len,value)
58+
59+ # Get a reference in case the value changes
60+ firstval_ref = CxxWrap. StdLib. cxxgetindex (CppInheritance. getData (ref_obj), 1 )
61+
62+ c_cb = make_callback (firstval_ref)
63+
64+ CppInheritance. set_callback (ref_obj, c_cb)
65+ return new (ref_obj, c_cb)
66+ end
67+ referred_object:: CppInheritance.VirtualCfunctionExtended
68+ callback:: CxxWrap.SafeCFunction # Needed to avoid garbage collection of the function
69+ end
70+
2871@testset " $(basename (@__FILE__ )[1 : end - 3 ]) " begin
2972
3073b = B ()
@@ -76,4 +119,23 @@ VirtualSolver.solve(a)
76119b = VirtualSolver. F (@safe_cfunction (x -> 2 x, Float64, (Float64,)))
77120VirtualSolver. solve (b)
78121
79- end
122+ let virt_extended_julia = CppInheritance. VirtualCppJuliaExtended (100000 ,1.0 )
123+ CppInheritance. set_callback (virt_extended_julia, double)
124+ @test CppInheritance. virtualfunc (virt_extended_julia) == 200000
125+ @time CppInheritance. virtualfunc (virt_extended_julia)
126+ end
127+
128+ let virt_extended_julia = CppInheritance. VirtualCfunctionExtended (100000 ,2.0 )
129+ CppInheritance. set_callback (virt_extended_julia, c_double)
130+ @test CppInheritance. virtualfunc (virt_extended_julia) == 400000
131+ @time CppInheritance. virtualfunc (virt_extended_julia)
132+ end
133+
134+ let virt_extended_julia = JuliaExtended (100000 , 4.0 )
135+ @test CppInheritance. virtualfunc (virt_extended_julia) == 1200000
136+ GC. gc ()
137+ @time CppInheritance. virtualfunc (virt_extended_julia)
138+ end
139+
140+ end
141+
0 commit comments