7

I’m trying to figure out how c bindings in crystal work. For starters I’m wondering how I would include a simple hello world c function into crystal. Always good to start with the basics right? Here’s the function I’d like to include:

#include <stdio.h>

void hello(const char * name){
  printf("Hello %s!\n", name);
}
too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Jake
  • 248
  • 2
  • 11
  • 2
    In the long term, you'd implement a dynamically linked library e.g. `libawesome.so` (which is complicated from the C side) and then you can use it like the usual examples: `@[Link("awesome")]`. – Oleh Prypin Mar 13 '17 at 22:04
  • @OlehPrypin Thanks for commenting. I was actually just looking into that. Much appreciated. – Jake Mar 13 '17 at 22:14
  • @Jake I recently created a small demo which shows how you can accomplish this: https://github.com/ethagnawl/crystal-c-interop-demo Hopefully it's instructive! – pdoherty926 Mar 14 '17 at 10:31
  • @pdoherty926, Thanks, I have shown it to a few people today they have been appreciative. Good job. Much appreciative from all. – Jake Mar 14 '17 at 18:14
  • @pdoherty926 Nice. You're solution is pretty close to mine. What is the advantage of using .a over .o like I used? .so seems pretty standard but potentially overkill for a simple 1 function lib. – isaacsloan Mar 14 '17 at 18:15
  • @isaacsloan I'm still very new to C, so take whatever I say with a grain of salt. (I'd be happy to be corrected by someone with more experience.) I'm not sure my approach is necessarily advantageous, but I believe creating a static library using ar allows you to bundle multiple object files and makes it easier to distribute your library. In case you're interested, [this](http://www.cs.dartmouth.edu/~campbell/cs50/buildlib.html) is the tutorial I used as a reference when creating my demo. (I've also added some reference links to the repo.) – pdoherty926 Mar 14 '17 at 18:33
  • @pdoherty926 Thanks. – isaacsloan Mar 14 '17 at 20:03

1 Answers1

15

That took me a bit to figure out as well. First you'll have to compile your C file into an object. In gcc you would run gcc -c hello.c -o hello.o.

Then in the crystal file you'll need to link to the C object. Here's an example:

#hello.cr
@[Link(ldflags: "#{__DIR__}/hello.o")]

lib Say 
  fun hello(name : LibC::Char*) : Void
end

Say.hello("your name")

Now you simply have to compile your crystal app and it will work. crystal build hello.cr

isaacsloan
  • 885
  • 6
  • 18
  • 2
    **Thanks** @isaacsloan, This helps a lot. I am excited to implement this into some of my future projects. – Jake Mar 13 '17 at 21:51
  • Not to necro an old thread, but can anyone speak to the performance of binding to C with Crystal? I know some other language have pretty high overhead with FFI type things, so is that also present in Crystal? – jocull Aug 29 '19 at 15:03