# Properly using \`finalizer\`, \`ccall\`, \`cconvert\` and \`unsafe\_convert\`

**URL:** <https://discourse.julialang.org/t/properly-using-finalizer-ccall-cconvert-and-unsafe-convert/6183>\
**Category:** General Usage\
**Tags:** question, ccall\
**Created:** [October 1, 2017, 6:08pm UTC](https://discourse.julialang.org/t/properly-using-finalizer-ccall-cconvert-and-unsafe-convert/6183 "2017-10-01T18:08:34Z")\
**Posts on this page:** 1\
**Showing post:** 10

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [October 2, 2017, 2:47am UTC](https://discourse.julialang.org/t/properly-using-finalizer-ccall-cconvert-and-unsafe-convert/6183/10 "2017-10-02T02:47:04Z")

</div>

> [@aytekinar](#):
>
> nor does my unsafe\_convert have any expression, as is forbidden in the documentation.

This is not forbidden, the forbidden thing is returning address of anything you allocated in the function.

> [@aytekinar](#):
>
> no difference between Ref{Ptr{Void}} and Ptr{Void} in Julia.

That’s not true, see below.

> [@aytekinar](#):
>
> Still I cannot understand your point above

Yes, your function will take a `void **` that’s fine, but if you want to mutate a `void*` in a C struct, you don’t define that field as `void** `, you’ll just define it as `void*`. And you’ll use it as

```c++
struct mytype {
    double v;
    void *ptr;
};

// and some code in a function
mytype *obj;
// ...
somefunction(obj->v, &obj->ptr);

```

And you can write a exact equivalent in julia.

> [@aytekinar](#):
>
> ```julia
> handleref = Ref{Ptr{Void}}(m.handle)
> res = ccall(funhandle, Cdouble, (Cdouble, Ref{Ptr{Void}}), m, handleref)
> m.handle = handleref[]
> 
> ```

No this is not necessary.

Also

> [@aytekinar](#):
>
> cconvert(t::Type{Cdouble}, m::MyType) = cconvert(t, value(m))

is fine but also not necessary. The validity of the `::Cdouble` doesn’t rely on the liveness of the `::MyType`. It’s certainly valid code though, just a little over-complicated.

The direct (and **invalid**!) way to implement the c++ code above in julia would simply be

```julia
ccall(somefunction, Cdouble, (Cdouble, Ptr{Ptr{Void}}), obj.v, pointer_to_objref(obj) + fieldoffset(typeof(obj), 2))

```

The only invalid part of the above code is that `pointer_to_objref(obj) + fieldoffset(typeof(obj), 2)` will not keep `obj` alive during the call. And the fix would be to somehow keep it alive. This can be acomplished either with `@gc_preserve` on 0.7 like

```julia
Base.@gc_preserve obj ccall(somefunction, Cdouble, (Cdouble, Ptr{Ptr{Void}}), obj.v, pointer_to_objref(obj) + fieldoffset(typeof(obj), 2))

```

which will be the preferred way **if** the convertion is callsite specific. On 0.6 where there’s no `@gc_preserve` or if this call convertion is used multiple times, it is preferred to use the `unsafe_convert`/`cconvert` and you can do this simply by putting that unsafe convert in, well, `unsafe_convert`, sth like.

```julia
Base.unsafe_convert(::Type{Ptr{Ptr{Void}}}, obj::MyType) = Ptr{Ptr{Void}}(pointer_to_objref(obj) + fieldoffset(typeof(obj), 2))

```

And simply do

```julia
ccall(somefunction, Cdouble, (Cdouble, Ptr{Ptr{Void}}), obj.v, obj)

```

The use of either `Ref{Ptr{Void}}` or `Ptr{Ptr{Void}}` is valid and doesn’t really matter. In fact, any `Ref` or `Ptr` type should work. I usually prefer `Ptr` though since `Ref` has special meaning and it is better to not mess with it.

> [@aytekinar](#):
>
> ```julia
> return ccall(funhandle, Cdouble, (Cdouble, Ptr{Ptr{Void}}), value(m),
> pointer_from_objref(m.handle))
> 
> ```

And I’ll also add that I can see how this is a failed attempt at translating the C code I translated above. The important thing to note here about the difference between C and julia is that there’s no C reference in julia. Even though it is not called so in C, `obj.field` produces a lvalue reference which is why `&` on it gives you the address **inside** `obj`. OTOH, `obj.field` always produce a rvalue in julia, or in another word, local variable assignment is never significant, you can insert as many of them as you want in the code and they’ll never make any difference in semantics. This means that `pointer_from_objref(m.handle)` corresponds to

```c++
{
    void *handle = m->handle;
    return &handle;
}

```

and it should be easy to see why it doesn’t give you the result you want. That’s also why you need to explicitly take the address of `m` in order to get the address of `handle` field in `m`.

---

_[View the full topic](https://discourse.julialang.org/t/properly-using-finalizer-ccall-cconvert-and-unsafe-convert/6183)._
