# 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:** 14

<div class="post-metadata">

### Author: ![anon61610682](https://avatars.discourse-cdn.com/v4/letter/a/ad7895/32.png) [@anon61610682](https://discourse.julialang.org/u/anon61610682)
#### Post date: [October 3, 2017, 7:56am UTC](https://discourse.julialang.org/t/properly-using-finalizer-ccall-cconvert-and-unsafe-convert/6183/14 "2017-10-03T07:56:33Z")

</div>

> [@yuyichao](#):
>
> That’s what I thought you mean and that shouldn’t be the case…

I can confirm that this is **not** working. Maybe I should open an issue then on GitHub. I might be wrongly implementing this, but I have tried **(not valid anymore, see below)**

```julia
unsafe_convert(t::Type{Ptr{Void}}, m::MyType) = m.handle
unsafe_convert(t::Type{Ref{Ptr{Void}}}, m::MyType) =
    Ref{Ptr{Void}}(pointer_from_objref(m) + fieldoffset(typeof(m), 2))

```

as well as the `Ptr{Ptr{Void}}` casted return type for the second overload above (with the proper `ccall` change), and I have always got

```julia
MethodError: Cannot `convert` an object of type MyType{Int64} to an object of type Ptr{Void}
This may have arisen from a call to the constructor Ptr{Void}(...),
since type constructors fall back to convert methods.

```

Anyways… For me, this is not a problem anymore, and I do think that the `Ptr{Ptr{Void}}` solution _should_ be the preferred way. That’s just more reasonable from its C counterpart.

> [@yuyichao](#):
>
> The special meaning is the special cconvert rule it has to pass a value by reference “implicitly” like ccall(…, (…, Ref{Int}, …), …, 1, …) You shouldn’t overload unsafe\_convert/cconvert(::Type{Ref{T}}, ::T2) where T2 can be reasonably converted to T. Anything else should be fine though I see no reason to do so… Note that you do need to overwrite both cconvert and unsafe\_convert though since the special cconvert behavior means that it doesn’t have a no-op default cconvert. I don’t see a reason to use Ref here though and since whether T2 can be reasonably converted to T is pretty fuzzy it’s better not to mess with it.

**EDIT & CORRECTION.** Actually, following this comment, I _think_ I have found the bug in my above code snippet. Since, as you pointed out, I _have to_ overload both of them, I need the below code snippet (assuming `T = Ptr{Void}` and `T2 = MyType`) to make things work correctly:

```julia
unsafe_convert(t::Type{Ptr{Void}}, m::MyType) = m.handle
cconvert(t::Type{Ref{Ptr{Void}}}, m::MyType) = m
# no reasonable conversion above. hence, define he conversion to be
# the object itself. then, let the unsafe convert do its job below
unsafe_convert(t::Type{Ref{Ptr{Void}}}, m::MyType) =
    Ptr{Ptr{Void}}(pointer_from_objref(m) + fieldoffset(typeof(m), 2))

```

Prior to your comment above, I was getting the method error I have mentioned in this message. Now I understand the reason: _lack of no-op cconvert_.

For all the help, thank you very much, once more!

---

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