Using Cxx to interface to a C++ library

I am trying to interface a c++ library (ntl) and am thinking of using the Cxx module.

Specifically, I’m looking to use the included C++ types directly in Julia, and perform mathematical operations on them using the C++ overloaded mathematical operators.
Is there a similar project which can be used a reference?

If not, can someone provide an outline of the necessary code?

Lastly, is this approach (using Cxx) the best approach in terms of runtime performance?

1 Like

A quick github search for “using Cxx” brought up three or four repositories but none that looked to me like Julia v1.x.

As far as I know Cxx.jl works with v1.1.0 (except windows, which has some issues).

Ah, sorry. I didn’t intend to imply that Cxx.jl doesn’t work on v1.1 – it does (and I have used it). I only meant that the project repos I found on github were using an older version of julia and Cxx.jl, which may not be helpful to OP.

1 Like

Since you’ve used Cxx, based on your experience how would you implement a wrapper for a mathematical types.
The types are declared in C++ as a class with overloaded versions of all basic math operations as well as additional methods.
I would like to import these types and functionality to be used from Julia, declaring new variables of these types in julia, converting to/from other types etc…

I was able to perform cxximport of the include file and ldlib open of the .so file, and I would appreciate help in the actual implementation (its easy to perform the c++ code with cxx"“”…“”" blocks, but that is not a true integration with julia)

My bad, sorry for misunderstooding.

this live demo from keno about wrapping quaternion might help:

3 Likes

I’ve seen this demo
I have struggled a bit with Cxx, It was easy enough to connect to the shared library (Libdl.dlopen) and open the library header with cxxinclude. However, the documentation is not for sufficient for me to wrap the actual C++ types. For example, I would like to define a Julia type ZZ which will server as a reference / alias to the C++ class ZZ. Then I would like the most succinct and efficient way to enable Julia native math operation on this type to call the corresponding C++ operators and interact with primitive Julia types using the C++ conversion functions.

  1. Can anyone share sample code that demonstrates how this could be done?

  2. Has anyone measured the performance penalty incurred by this cross-language wrappers?

you could take a look at std.jl for some examples on how to wrap C++ code:

https://github.com/JuliaInterop/Cxx.jl/blob/8c2b5c14519e82eb933fadf3f3df66b7bf1b41aa/src/std.jl#L13

2 Likes

Thanks for the pointer
I have an initial working version (see below)
Before I continue wrapping the rest of the library, please review and comment if this is the “correct” way, both in terms of ease of use and more importantly in terms of performance (i.e. making sure there are no superfluous object constructions and copying)

using Cxx
using Libdl

Libdl.dlopen("/usr/local/lib/libntl.so", Libdl.RTLD_GLOBAL)

addHeaderDir("/usr/local/include", kind=C_System)

cxxinclude("NTL/ZZ.h")
cxxinclude("sstream")
cxxinclude("string")


const NTL_ZZ = cxxt"NTL::ZZ"
cxx"""
std::string zzToString(const NTL::ZZ& z) {
    std::stringstream buffer;
    buffer << z;
    return buffer.str();
}
"""
struct ZZ <: Number
    val::NTL_ZZ
    ZZ(n) = new(@cxx NTL::ZZ(n))
end
Base.:+(x::ZZ, y::ZZ) = ZZ(@cxx(x.val+y.val))
Base.:-(x::ZZ, y::ZZ) = ZZ(@cxx(x.val-y.val))
Base.:*(x::ZZ, y::ZZ) = ZZ(@cxx(x.val*y.val))
Base.:/(x::ZZ, y::ZZ) = ZZ(@cxx(x.val/y.val))
Base.:convert(::Type{ZZ}, x::T) where {T<:Integer} = ZZ(x)
Base.:promote_rule(::Type{ZZ}, ::Type{I}) where {I<:Integer} = ZZ
function Base.show(io::IO, x::ZZ)
    zz_str = @cxx zzToString(x.val)
    print(io, unsafe_string(zz_str))
end
1 Like