Develop "Julian" API for a C++ library?

I have an vendor-produced C++ library that I would like to write a Julia wrapper for (I only have headers and shared objects for it). The typical use case is that the library is called from a user-created file that just has a main method (basically, a simulation script: initialize things, and loop over steps setting simulation state to suit the creator of the script). I realize that there might be good ways of doing this, but probably not one single best way of doing this.

What I am really looking for is a link to some discussion of how other people did this, perhaps projects on Github that I can peruse? The existing C++ code is typically called like this:

auto w = Widget();
w->init();
for (int i = 0; i < N; ++i) {
    Foo *a = w.get_foo();
    a->prop1 = 1;
    a->prop2 = 2;
    a->method("bar");

    w->frob();
}

I was thinking that the look of a Julia wrapper might be:

w = Widget()
init(w)

for i ∈ 1:N
    a = get_foo(w)
    a.prop1 = 1
    a.prop2 = 2
    method(a, "bar")

    frob(w)
end

Did you manage to take a look at the JuliaInterop/CxxWrap.jl: Package to make C++ libraries available in Julia package?

Also - you might find the issues section instructive for additional challenges people faced.

Disclaimer: I have no practical experience with calling C/C++ from Julia. I just did some reading on the subject out of curiosity.

1 Like

I have a couple of dynamic libraries that I needed to access. I have used ccall statements. I have started to use Clang to generate the wrapper code. This gives a good start at developing the code I require.

I one case I created the ccall statements by hand and then when I learned about Clang I tried it. In the simpler calls it created the code I wanted. In other cases it was a really good start, eliminating much tedious work.

2 Likes

Thanks for the suggestions, I hadn’t thought of looking in “issues,” but that was interesting as well. I had also looked at PyCall.jl and PythonCall.jl for some ideas.

The real issue is that the API is very non-Julian on the surface. I’m new to Julia, and frankly have been amazed at how well designed the APIs are in Julia. I have been used to seeing OO APIs designed similarly to the one that I am trying to wrap now: You have a tree-like relationship with some sort of manager object (simulation object in my case). The simulation has things that it manages that you can get at with . or ->, and sometimes those things have sub-objects that they manage.

So, I have collections of methods and parameters fields and methods in an object, and some of the objects may themselves contain methods and objects as well.

I have been trying to use overloads of Base.getproperty to handle getting the properties, but I wasn’t sure how to use Base.getproperty (or somethings similar) to:

# may not even be possible:
main_wrapped_object.method()
main_wrapped_object.subobject.method()

… or if that was even a good idea. I wasn’t expecting this to be easy, and I realized that I may end up having to radically alter the look of the API on the Julia side. Right now for methods and functions that ends up being changing API calls like animal.eat(food) to feed(animal, food) (i.e., change the verb).

Maybe I could incorporate this trick from SO?