# How to make Julia call C/C++ coded function

**URL:** https://discourse.julialang.org/t/how-to-make-julia-call-c-c-coded-function/54780
**Category:** Performance
**Tags:** question, ccall, cxx
**Created:** [February 7, 2021, 10:58am UTC](https://discourse.julialang.org/t/how-to-make-julia-call-c-c-coded-function/54780 "2021-02-07T10:58:19Z")
**Posts on this page:** 1
**Showing post:** 5

<div class="post-metadata">

### Author: ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)
#### Post date: [February 7, 2021, 2:35pm UTC](https://discourse.julialang.org/t/how-to-make-julia-call-c-c-coded-function/54780/5 "2021-02-07T14:35:43Z")

</div>

To call C you don’t need anything, as it is native in Julia core. To call C++ you need instead a package.  
Here an excerpt from the relevant chapter of my “_Julia Quick Syntax Reference: A Pocket Guide for Data Science Programming_” book where CxxWrap.jl is used.

## Julia ⇄ C

As said, calling C code is native to the language and doesn’t require any third-party code.

Let’s fist build a C library. We show this in Linux using the GCC compiler. The procedure in other environments would be similar but not necessarily identical:

myclib.h:

```C
extern int get2 ();
extern double sumMyArgs (float i, float j);

```

myclib.c:

```julia-auto
int get2 (){
 return 2;
}
double sumMyArgs (float i, float j){
 return i+j;
}

```

Note that we need to define the function we want to use in Julia as `extern` in the C header file.

We can then compile the shared library with `gcc`, a `C` compiler:

- `gcc -o myclib.o -c myclib.c`
- `gcc -shared -o libmyclib.so myclib.o -lm -fPIC`

We are now ready to use the `C` library in Julia:

```julia-auto
const myclib = joinpath(@ __DIR__ , "libmyclib.so")
a = ccall((:get2,myclib), Int32, ())
b = ccall((:sumMyArgs,myclib), Float64, (Float32,Float32), 2.5, 1.5)

```

The `ccall` function takes as the _first_ argument a tuple `(function name, library path)` where the library path must be expressed in term of full path, unless the library is in the search path of the OS.  
If it isn’t, and we still want to express it in terms relative to the file we are using, we can use the macro `@ __DIR__ ` that expands to the absolute path of the directory of the file itself.  
The variable hosting the full path of the library must be set constant, as the tuple acting as first argument of `ccall` must be _literal_.

The _second_ argument of `ccall` is the return type of the function. Note that while C `int` maps to either Julia `Int32` or `Int64`, C `float` maps to Julia `Float32` and C `double` maps to Julia `Float64`. In this example we could have used instead the corresponding Julia type aliases `Cint`,`Cfloat` and `Cdouble` (within others) in order to avoid memorising the mapping.

The _third_ argument is a tuple of the types of the arguments expected by the C function. If there is only one argument, it must still be expressed as a tuple, e.g. `(Float64,)`.

Finally the remaining arguments are the arguments to pass to the C function.

We have just “touched the surface” here. Linking C (or Fortran) Code can become pretty complex in real-case situations, and consulting the [Calling C and Fortran Code · The Julia Language](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/)[official documentation] indispensable.

### Julia ⇄ C++

As for C, C++ workflow is partially environment-dependent. We use in this section Cxx.jl under Linux, although Cxx.jl has also an experimental support for Windows footnote:cxxRequirement[`Cxx` requires a version of Julia ≥ 1.1]..

It’s main advantage over other C++ wrap modules (notably [CxxWrap.jl](https://github.com/JuliaInterop/CxxWrap.jl))  
is that it allows working on {C++ code in multiple ways depending on the workflow that is required.

#### Interactive C++ prompt

[…]

#### Embed C++ code in a Julia program

Aside the REPL prompt, we can use C++ code in our Julia program without ever leaving the main Julia environment. Let’s start with a simple example:

```julia-auto
using Cxx

# Define the C++ function and compile it
cxx"""
#include<iostream>
void myCppFunction() {
   int a = 10;
   std::cout << "Printing " << a << std::endl;
}
"""
# Execute it
icxx"myCppFunction();" # Return "Printing 10"
# OR
# Convert the C++ to Julia function
myJuliaFunction() = @cxx myCppFunction()
# Run the function
myJuliaFunction() # Return "Printing 10"

```

The workflow is straight-forward: we first embed the {C++ code with the `cxx"..."` string macro.

We are then ready to “use” the functions defined in `cxx"..."` either calling them directly with C++ code embedded in `icxx"..."` or converting them in _Julia_ function with the `@cxx` macro and then using Julia code to call the (Julia) function.

The above example however doesn’t imply any transfer of data between Julia and C++, while if we want to embed C++, most likely it is in order to pass some data to C++ and retrieve the output to use in our Julia program.

The following example shows how data transfer between Julia and C++ (both ways) is handled automatically for elementary types:

```julia-auto
----
using Cxx
cxx"""
#include<iostream>
int myCppFunction2(int arg1) {
   return arg1+1;
}
"""
juliaValue = icxx"myCppFunction2(9);" # 10
# OR
myJuliaFunction2(arg1) = @cxx myCppFunction2(arg1)
juliaValue = myJuliaFunction2(99) # 100

```

However when the transfer involves complex data structures (like arrays or, as in the following example, arrays of arrays) things become more complex, as the Julia types have to be converted in the C++ types, and vice versa:

```julia-auto
using Cxx
cxx"""
#include <vector>
using namespace std;
vector<double> rowAverages (vector< vector<double> > rows) {
  // Compute average of each row..
  vector <double> averages;
  for (int r = 0; r < rows.size(); r++){
    double rsum = 0.0;
    double ncols= rows[r].size();
    for (int c = 0; c< rows[r].size(); c++){
      rsum += rows[r][c];
    }
    averages.push_back(rsum/ncols);
  }
  return averages;
}
"""
rows_julia = [[1.5,2.0,2.5],[4,5.5,6,6.5,8]]
rows_cpp = convert(cxxt"vector< vector< double > > ", rows_julia)
rows_avgs = collect(icxx"rowAverages($rows_cpp);")
# OR
rowAverages(rows) = @cxx rowAverages(rows)
rows_avgs = collect(rowAverages(rows_cpp))

```

The conversion from Julia data to C++ data (to be used as argument(s) of the C++ function) is done using the familiar `convert(T,source)` function, but where `T` is here given by the expression returned by `cxxt"[Cpp type]"`. +  
The converted data can then be used in the C++ function call, with the note that if the direct call form of `icxx"` is used, this has to be interpolated using the dollar `$` operator.

Finally, `collect` is used to copy data from the C++ structures returned by the C++ function to a Julia structure (avoiding copying is also possible using pointers).

#### Load a C++ library

The third way to use C++ code is to load a C++ library and call directly the functions defined in that library. The advantage is that the library doesn’t need to be aware that will be used in Julia (i.e. no special Julia headers or libraries are required at compile time of the C++ library) as the wrap is done entirely in Julia. This has the advantage that pre-existing libraries can be reused.

Let’s reuse our last example, but this time we compile it in a shared library.

mycpplib.cpp:

```julia-auto
#include <vector>
#include "mycpplib.h"
using namespace std;
vector<double> rowAverages (vector< vector<double> > rows) {
  // Compute average of each row..
  vector <double> averages;
  for (int r = 0; r < rows.size(); r++){
    double rsum = 0.0;
    double ncols= rows[r].size();
    for (int c = 0; c< rows[r].size(); c++){
      rsum += rows[r][c];
    }
    averages.push_back(rsum/ncols);
  }
  return averages;
}

```

mycpplib.h:

```julia-auto
#include <vector>
std::vector<double> rowAverages (std::vector< std::vector<double> > rows);

```

We can then compile the shared library with `g++`, a C++ compiler:

- `g++ -shared -fPIC -o libmycpplib.so mycpplib.cpp`

We are now ready to use it in Julia:

```julia-auto
using Cxx
using Libdl # <1>

const path_to_lib = pwd()
addHeaderDir(path_to_lib, kind=C_System) # <2>
cxxinclude("mycpplib.h") # <3>
Libdl.dlopen(joinpath(path_to_lib, "libmycpplib.so"), Libdl.RTLD_GLOBAL) # <4>

rows_julia = [[1.5,2.0,2.5],[4,5.5,6,6.5,8]]
rows_cpp = convert(cxxt"std::vector< std::vector< double > >", rows_julia)
rows_avgs = collect(icxx"rowAverages($rows_cpp);")

```

The only new things here is that we need to explicitly load the standard lib `Libdl` (1 ), add the C++ header(s) (2 and 3) and finally open the shared library (4).

We are now able to use the functions defined in the library as if we embedded the C++ code in the Julia script.

---

_[View the full topic](https://discourse.julialang.org/t/how-to-make-julia-call-c-c-coded-function/54780)._
