C null pointer to custom type

ccall

#1

I am coupling to a C library and would like to pass null pointers to a function. However, I want to pass a null pointer of type Ptr{<mytype>}. When I do that I end up with a convert error, because C_NULL of Ptr{Void}. It would be most straightforward if I could just use C_NULL everywhere.

Is there a way to write a custom convert function? I tried
convert(::Type{Ptr{<mytype>}}, C_NULL) = Ref{<mytype>}(0)
but that didn’t seem to do anything.


#2

what is your actual ccall?

This looks good for me

> struct Foo end

> Ptr{Foo}(C_NULL)
Ptr{Foo} @0x0000000000000000

#3

reinterpret(Ptr{foo}, 0) does the job for me. A null-pointer is after all an integer-zero.


#4

There is no need for reinterpret here. The standard way to do it is just to use the constructor, as already shown, (which just bitcasts C_NULL to Ptr{Foo} but there is a reason why there exists higher-level interfaces).


#5

So an example would be for the function foobar:
ccall((:foobar, lib_include), Cint, (Ptr{foo}), C_NULL)
which does not work because C_NULL is of type Ptr{Void}.
So is there a way to convert C_NULL automatically to a type of Ptr{foo}?


#6

Does ccall((:foobar, lib_include), Cint, (Ptr{foo},), Ptr{foo}(C_NULL)) work for you?


#7

Yes, that works. But I was wondering if there was a way to do that automatically? In the same way a C_NULL can be used for a Ptr{Cint}?


#8

Perhaps

Base.cconvert(::Type{Ptr{Foo}}, ::Ptr{Void}) = Ptr{Foo}(C_NULL)

#9

But I do not suggest that changing the behaviour of builtin type like
Cint,
since that will affect other packages (even Base).