the proper way to declare C void pointers in Julia

c, julia, void-pointers

Solution

Your code looks almost fine. But be careful! Any small error, like the one you have here, can cause a segmentation fault:

p = Ref{Ptr{Void}}()
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p)
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p)
                                        # error here  ^

The correct way to do it is

p = Ref{Ptr{Void}}()
ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p)
ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p[])
                                             # fixed  ^

The easiest way to understand where to use `p` and `p[]` is to think of the corresponding C code. In C, we write

void *p;
create_new_thing(&p)
do_stuff_to_thing(p)

Julia objects do not have first-class memory addresses like C objects do, so we must use `p = Ref{Ptr{Void}}()` in Julia to get a memory address. This object, as a ref, behaves like `&p` in C. That means to get the object itself, `p` in C, we need to use `p[]` in Julia.

So the equivalent in Julia is

p = Ref{Ptr{Void}}()                 # this p corresponds to &p in C
ccall(:create_new_thing, ..., p)     # like &p
ccall(:do_stuff_to_thing, ..., p[])  # like *(&p); that is, like p

Problem

Ok, I originally badly screwed up my formulation of this question (it's more than a year now since I seriously wrote C++ code and I have pretty limited experience with pure C), so let's try again. Some C code is written to expect you to do something like the following ``` void* p; create_new_thing(&p); //p is now a new thing do_stuff_to_thing(p); //something happened to p ``` My question is how to create the object `p` in Julia. Right now I believe the answer to be ``` p = Ref{Ptr{Void}}() ccall((:create_new_thing, :lib), Void, (Ptr{Ptr{Void}},), p) ccall((:do_stuff_to_thing, :lib), Void, (Ptr{Void},), p) ``` Furthermore, I believe the same code but with `p` declared instead as `p = Array(Ptr{Void}, 1)` also works. I do however find the whole distinction between `Ref` and `Ptr` in Julia very confusing, mostly because they seem to get converted between each other in ways I cannot keep track of.

Original source