Open peremato opened 1 week ago
This can be avoided by using a small lambda function instead of the member-function pointer, i.e.:
type.method("+", [](const Hist& h, double f) { return h+f; });
type.method("+", [](const Hist& h, const Hist& f) { return h+f; });
Then the generated functions will be more strict regarding the arguments (and only allow Union{Main.Types.Hist, ConstCxxRef{<:Main.Types.Hist}, CxxRef{<:Main.Types.Hist}}
as first argument).
For a member function libcxxwrap-julia generates two methods, one for the Ptr
type as a base object and one for the Ref
type:
/// Define a member function, const version
template<typename R, typename CT, typename... ArgsT, typename... Extra>
TypeWrapper<T>& method(const std::string& name, R(CT::*f)(ArgsT...) const, Extra... extra)
{
m_module.method(name, [f](const T& obj, ArgsT... args) -> R { return (obj.*f)(args...); }, extra... );
m_module.method(name, [f](const T* obj, ArgsT... args) -> R { return ((*obj).*f)(args...); }, extra... );
return *this;
}
Which results in these CppFuntionInfo:
CxxWrap.CxxWrapCore.CppFunctionInfo(:+, Any[ConstCxxRef{Main.Types.Hist}, Float64], Any, Main.Types.HistAllocated, Ptr{Nothing} @0x00007f6393220600, Ptr{Nothing} @0x000000002585c150, Base, "", Any[], Any[], 0)
CxxWrap.CxxWrapCore.CppFunctionInfo(:+, Any[ConstCxxPtr{Main.Types.Hist}, Float64], Any, Main.Types.HistAllocated, Ptr{Nothing} @0x00007f639321c520, Ptr{Nothing} @0x0000000027d36930, Base, "", Any[], Any[], 0)
But CxxWrap will allow Ptr{Cvoid}
when mapping ConstCxxPtr{T}
to the arguments here:
https://github.com/JuliaInterop/CxxWrap.jl/blob/ad11b163cc47c999b6edc36b137a182d78478467/src/CxxWrap.jl#L575
producing this signature:
:((Base).:+(arg1::Union{Ptr{Nothing}, ConstCxxPtr{<:Main.Types.Hist}, CxxPtr{<:Main.Types.Hist}}, arg2::Union{Float64, Int64, Irrational}; )::Main.Types.HistAllocated
Thanks very much for the explanation and way out. I have tested and indeed with lambdas I get the signature:
+(arg1::Union{Main.Types.Hist, ConstCxxRef{<:Main.Types.Hist}, CxxRef{<:Main.Types.Hist}}, arg2::Union{Float64, Int64, Irrational})
The problem I have now is that the wrapper code is genererated by WrapIt.jl and I need to find out why is using static_cast
instead of lambdas.
While wrapping a C++ type that provides operator+ breaks the REPL in a very unexpected manner. For example using the
?
to get the help of a entity, the wrapped operator is selected by the multiple-dispatch when trying to call the function+(arg1::Ptr{Nothing}, arg2::Int64)
. Here is the error:I am attaching a reproducer.
and the Julia code to trigger the error: