Julia calling C: A minimal example

This blog is a “Hello World” example of Julia calling C.

We start of by at bit of C code we want to call from Julia. We write the following in calc_mean.c

double mean(double a, double b) {
  return (a+b) / 2;
}

To build the library, we need to create a Makefile

CC=gcc 
 
CFLAGS=-c -Wall -fPIC
 
SOURCES=calc_mean.c 
OBJECTS=$(SOURCES:.c=.o)
 
.c.o:
    $(CC) $(CFLAGS) $< -o $@ 
 
lib: $(OBJECTS)
    $(CC) -shared -fPIC -o libmean.so $(OBJECTS)
 
clean:
    rm *.o *.so

The option fPIC and -shared are essential for Julia to be able to resolve the function in our library. Now we are almost ready to build our library. From the bash terminal we invoke:

make lib

This will generate a libmean.so file.

In Julia we call the function in our c library by

x=ccall((:mean,"libmean"),Float64,(Float64,Float64),2.0,5.0)
println(x)
3.5

For this to work,

  • Julia must be running either on the same path where libmean.so resides,
  • the path to libmean.so is in LD_LIBRARY_PATH, or
  • the path to the library is pushed to Libdl.DL_LOAD_PATH via

push!(Libdl.DL_LOAD_PATH,"path_to_libmean.so")

P.S. Thanks to Christopher Rackauckas for tips on Julia highlighting.

5 thoughts on “Julia calling C: A minimal example

  1. Hi Perfectionatic’s

    I’m studying julia and I liked the site. An error occurred while running “make”:

    Makefile:9: *** missing separator. Stop.

    How to solve?

  2. Pingback: Julia calling C: A more minimal example | Perfectionatic's blog

  3. Hello,
    thank you for your post si very helpfull. I’ve already created the library and i’m g¡having this error.
    julia> x=ccall((:mean,”libmean”),Float64,(Float64,Float64),2.0,5.0)
    ERROR: error compiling anonymous: could not load library “libmean”
    I think it’s a problem with the thing that you mentioned at the end but i did
    push!(Libdl.DL_LOAD_PATH,”path_to_libmean.so”) and it still doesnt work. I think i’m doing a stupid thing but i dont know what:
    Could you please help me?

    Thank you very much

    Sara

  4. Hello Sara,

    Just to be sure ”path_to_libmean.so” in the example command is just a string pointing to where your libmean.so lives. For example on a Linux systems, this would look something like “/home/sara/juliacode/meanlib/”. So the basic steps are:
    1. Make sure that “libmean.so” was actually created
    2. Find its full path
    3. Use that path in push!(Libdl.DL_LOAD_PATH,”path_to_libmean.so”)

    Hope this helps.

Leave a Reply