Am I missing something or you’re trying to push to an array that doesn’t exist in the C-side of your code? I assume your is an oversimplified excerpt of your real-world application, but this less contrived example works
C = """
typedef struct CParticle {
double charge;
double E;
double weight;
} CParticle;
CParticle simulate2() {
CParticle cp;
cp.charge = 0;
cp.E = 1;
cp.weight = 2;
return cp;
}
"""
struct CParticle
charge::Cdouble
E::Cdouble
weight::Cdouble
end
run(pipeline(`gcc -x c -g -shared -fPIC - -o lib.so`; stdin = IOBuffer(C)))
lib = "./lib.so"
function main()
ret = CParticle[]
push!(ret, @ccall lib.simulate2()::CParticle)
@show ret
end
main()
Am I missing something or you’re trying to push to an array that doesn’t exist in the C-side of your code?
What do you mean by does not exist in the C-side? My naive expectation was that I could execute arbitrary Julia code in a function pointer that I pass to C? Ok arbitrary is an exaggeration, there are various caveats e.g. multi-threading, GC. But other then GC issues, which should not apply here, whats the problem with manipulating some heap-allocated julia object like a vector in this callback?
I assume your is an oversimplified excerpt of your real-world application, but this less contrived example works
In my real example, a simulation is running and it accepts callbacks, which are executed at various events, so one can extract information. I cannot handle my real case by your return value trick.
A “canonical” callback function should accept a void * userdata argument for extracting information, in this way, there is no need to use closures.
function f(x::CParticle, userdata::Vector{CParticle})::Cvoid
push!(userdata, x);
return nothing
end
function main()
ret = CParticle[]
f_c = @cfunction f Cvoid (CParticle, Vector{CParticle})
@ccall lib.simulate(f_c::Ptr{Cvoid}, ret::Any)::Cvoid
@show ret
end