Easy call to Julia functions from C++ using C++14

Hi guys!

I just want to share a very simple code I created in C++ (using standard C++14) to make calls to Julia functions easier. My use case is that I need to call a lot of functions from my package SatelliteToolbox.jl and all the values are handle by the C++. Hence, there is not reuse of packed variables, i.e., no concerns about GC.

The code I am using (please, let me know if I am making something bad) is:

#include <iostream>
#include <string>
#include <vector>

extern "C" {
#include <julia.h>
}

void pack_jl_vars(jl_value_t** args_jl, int v) {
    *args_jl = jl_box_int64(v);
}

void pack_jl_vars(jl_value_t** args_jl, double v) {
    *args_jl = jl_box_float64(v);
}

template<typename T, typename... Ts>
void pack_jl_vars(jl_value_t** args_jl, T v, Ts... s)
{
    pack_jl_vars(args_jl, v);
    pack_jl_vars(args_jl + 1, s...);
}

template<typename... Targs>
jl_value_t* jl_call(jl_function_t* func_jl, Targs... args) {
    int nargs = sizeof...(args);
    jl_value_t** args_jl;
    jl_value_t* ret;

    JL_GC_PUSHARGS(args_jl, nargs);
    pack_jl_vars(args_jl, args...);
    ret = (jl_value_t*)jl_call(func_jl, args_jl, nargs);
    JL_GC_POP();

    return ret;
}

template<typename... Targs>
jl_value_t* jl_call(std::string func_str, Targs... args) {
    jl_function_t* func_jl = jl_get_function(jl_base_module, func_str.c_str());
    return jl_call(func_jl, args...);
}

In this case, I can call any Julia function in jl_base_module by just:

    jl_value_t* ret = jl_call("+", M_PI, 3.0, 2.0, 1.0, 1);

This code is handling only integers and floats, but can easily be expanded by adding more overloads to pack_jl_vars.

6 Likes