@ccall and pointer to structure

Hello,
I’ve a c function that updates (pass by parameter) a pointer to a structure. so in @ccall I should use Ptr{my_struct} types . But I cannot create the structure pointer as method pointer(whatever::MyStruct) does not exist… What is the best way to achieve that ?
Thks a lot
Br Yves-Julien

edit: I already have a solution but really not sure it’s the best i.e. using a pointer to vector of Uint8 of corresponding size and reinterpret the binary data to correct types

Use a Ref to hold your object, and pass that through the ccall:

e.g.

julia> struct MyStruct
           field::Int
       end

julia> mydata = MyStruct(1)
MyStruct(1)

julia> ref_mydata = Ref(mydata)
Base.RefValue{MyStruct}(MyStruct(1))

julia> @ccall printf("%p\n"::Cstring, ref_mydata::Ptr{MyStruct})::Cint;
0x78e800432b40
1 Like

This section has a good breakdown of when to use Ref vs Ptr:: Calling C and Fortran Code · The Julia Language

Here’s another very simple example:

julia> const Ctime_t = Int64
Int64

julia> t = Ref(Ctime_t(0))
Base.RefValue{Int64}(0)

julia> @ccall time(t::Ref{Ctime_t})::Ctime_t
1730135137

julia> t[]
1730135137

julia> @ccall time(t::Ref{Ctime_t})::Ctime_t
1730135140

julia> t[]
1730135140

Thanks, this works ! I was confused because I tried a more concise way that work only I think if the structure is used as input to the function as below:

struct MyStruct
           field::Int
       end

julia> mydata = MyStruct(1)
MyStruct(1)

julia> @ccall printf("%p\n"::Cstring, Ref(mydata)::Ptr{MyStruct})::Cint;

But if the functions changes the structure, it is not reflected in the julia structure. To my understanding it’s because the pointer is created in the function call thus valid only at function call so the after it is GC and therefore could not alter the content of mydata…
Am I correct ?

That identifier there — mydata — is just a name for you that can serve as a name for the value MyStruct(1). MyStruct itself is not mutable; it cannot change. And mydata can only become the name of a different thing if you explicitly assign something else to it, deciding you have a better use for that name.

When you put a value in a box like a Ref, then you (or your C code) can decide to switch out what’s on the inside of that box. If you throw away the box (or just don’t name it anything meaningful), then you won’t be able to observe the change.

In short, Julia’s variables don’t have the same pointer semantics that you might be used to.

If the struct isn’t mutable, it can’t change, so julia will assume it hasn’t.

1 Like