Calling C from Julia (i) : Simple arrays

One of the nice things about Julia is its simple ability to call functions written in other languages. In An ideal world, a function is always better written natively, but for libraries of functions which already exist in say C, or Fortran, it may be more economical to call them from Julia.

The only real bugbear is the same one i found when trying to call a function written in language X  from language Y, namely interoperability between datatypes. But having said that it isn’t terrible, just requires looking up the documentation of Julia-C datatype equivalents. The rest is child’s play. So as an example, let’s look at the simple process of calling a C function called vectorMean(), which just calculates the mean of a series of numbers. Here’s the C code:

double vectorMean(int *arr, int n)
{
    int i, sum=0;
    double mean;
    for (i=0; i<n; i=i+1)
        sum = sum + arr[i];
    mean = sum / (double)n;
    return mean;
}

Nothing to it right? It’s then compiled with:

gcc -Wall -shared -o myC.so mean.c

Creating a library file called myC.so. The associated Julia code to call this function is:

1  x = collect(Cint, 1:5)
2  println(x)
3  aM = ccall((:vectorMean, "myC.so"), Float64, 
              (Ptr{Cint},Cint), x, 5)
4  println("Mean = ", aM)

The first line of code uses Julia’s collect() function to  create an array of 5 items, with values 1..5 in each respective element. Notice the use of the type Cint. This specifies that the array has the same type as an int in C. Line 3 contains the code that is the crux of calling C functions from Julia: ccall(). In this particular scenario, as vectorMean() returns a value, that value is stored in the variable aM. The function ccall() has a number of components. The first is:

(:vectorMean, "myC.so")

This specifies the name of the external C function, and the library in which it is contained. The next parameter specifies the type of the return item, if there is one. In this case it is the type Float64 (the Julia equivalent of double). The third section:

(Ptr{Cint},Cint)

specifies the Julia datatypes for the function parameters of the C function. In this case vectorMean() has a pointer to an int (array), and an int. The use of Ptr specifies that the parameter is a pointer, and both are of type Cint. Finally the last set of parameters of ccall() specify the actual Julia variables to be passed to vectorMean().

x, 5

So running the Julia code will pass the array x, and the value 5 to the C function vectorMean() in the library myC.so, calculate the mean, and return this value to aM.

Now 2D arrays are a little trickier, but not that hard… we’ll cover those in the next post.

3 thoughts on “Calling C from Julia (i) : Simple arrays

  1. Can you please clarify what you meant by “library file”? Is it just a file with the included libraries and function definitions? I’d appreciate the help.

    1. The library file is the “.so”, or shared object file. It contains the C functions which are to be accessed by the Julia program.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.