Hi
I’m trying to wrap a C library, and I can’t figure out how references are handled in ccall.
Here is my study case: I have a simple C file, called jlptrtest.c, consisting of just this:
void put_7( int *i ) {
*i = 7;
}
I’ve compiled it with cc jlptrtest.c -fPIC -shared -o libptrtest.so and am now trying to use it from Julia. I want to access the value 7. I’ve tried
a = 13
ccall( (:put_7, "libptrtest"), Cvoid, (Ref{Cint},), a )
println(a)
and it prints 13, not 7. Which type should a have, and how do I have to write the ccall so that I can get my 7?
Thanks in advance.
Simon
simon-anders:
Which type should a have
The one you declare you’re passing to the C function, Ref{Cint}. Note that Cint is an alias for Int32, but integer literals on a 64-bit Julia are Int64
julia> a = Ref{Cint}(13)
Base.RefValue{Int32}(13)
julia> ccall((:put_7, "./libptrtest.so"), Cvoid, (Ref{Cint},), a)
julia> a
Base.RefValue{Int32}(7)
julia> a[]
7
For reference, see the relevant section of the manual: Passing Pointers for Modifying Inputs
2 Likes
Gnimuc
January 18, 2021, 1:37am
3
ccall( (:put_7, "libptrtest"), Cvoid, (Ref{Cint},), a )
What happened here was
a was Base.cconvert-ed to a tmp_var of type Ref{Cint}
the put_7 function in your c library edited the value of tmp_var
a is left untouched
The fix is to define a as a Ref: a_ref = Ref{Cint}(13)
4 Likes
Thanks a lot to both of you. I though I had tried that, too, but obviously I hadn’t. Now it works.
2 Likes