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)
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
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.
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:
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!