Crystal C binding, simple hello world example.
Asked Answered
S

1

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);
}
Sweatbox answered 13/3, 2017 at 21:24 Comment(7)
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")].Kalakalaazar
@OlehPrypin Thanks for commenting. I was actually just looking into that. Much appreciated.Sweatbox
@Sweatbox I recently created a small demo which shows how you can accomplish this: github.com/ethagnawl/crystal-c-interop-demo Hopefully it's instructive!Erminiaerminie
@pdoherty926, Thanks, I have shown it to a few people today they have been appreciative. Good job. Much appreciative from all.Sweatbox
@Erminiaerminie 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.Glosso
@Glosso 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 is the tutorial I used as a reference when creating my demo. (I've also added some reference links to the repo.)Erminiaerminie
@Erminiaerminie Thanks.Glosso
G
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

Glosso answered 13/3, 2017 at 21:44 Comment(2)
Thanks @isaacsloan, This helps a lot. I am excited to implement this into some of my future projects.Sweatbox
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?Magnanimous

© 2022 - 2024 — McMap. All rights reserved.