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