text: 2015-12-16
  C linkable libraries with Pony
  Note 2017-08-01: Recent releases of Pony have changed some of the details of interacting with C. This post has been updated to work with these changes as of Pony 0.16.1.
  My quick look at Pony post covered how to use the FFI to call C code from a Pony program. It's also possible to compile Pony code to a C library that can be linked into a C program. This allows integrating Pony into existing C projects without having to convert the C project into a library to be called by Pony.
  I've put a small example of how to do this on github at.
  Pony has a special type of actor that will result in a C compatible interface being generated. The syntax for this is
  actor@. The example in the project is:
  actor@ Foo new create() => None be hi() => @printf[I32]("Hi\n".cstring())
  This creates a C compatible actor called
  Foo. It has a constructor
  create and a behaviour
  hi. The constructor does nothing and only exists in the example to show how to call it from C. The
  hi behaviour calls the C function
  printf using the Pony FFI. With a file
  main.pony containing this code in a
  clib directory it can be built with:
  $ ponyc -l clib Building builtin -> packages/builtin Building clib -> clib Generating Optimising Writing ./clib.o Archiving ./libclib.a
  The
  -l switch to
  ponyc results in a static library being built instead of an executable. A
  libclib.a is generated containing the compiled Pony code. A
  clib.h is also generated containing the C function declarations for creating and interacting with any
  actor@ instances. For the
  Foo actor this looks like:
  typedef struct Foo Foo; Foo* Foo_Alloc(); None* Foo_tag_hi_o__send(Foo* self); Foo* Foo_tag_create_o__send(Foo* self);
  Pony has a runtime that needs to be initialized from C and a scheduler that needs to be started. The definitions for these runtime functions can be found in the
  ponyc source in libponyrt/pony.h. This needs to be included by the C program. A basic C driver for the example project is:
  #include <stdio.h> #include "clib.h" #include "pony.h" int main(int argc, char** argv) { pony_init(argc, argv); Foo* x = Foo_Alloc(); Foo_tag_hi_o__send(x); Foo_tag_create_o__send(x); pony_start(true, true); return 0; }
  This sould be compiled and linked against
  libclib.a and
  libponyrt.a:
  export PONYRT_INCLUDE=/path/to/ponyc/src/libponyrt/ export PONYRT_COMMON=/path/to/ponyc/src/common export PONYRT_LIB=/path/to/ponyc/build/release/libponyrt.a gcc -o test -I. -I $(PONYRT_INCLUDE) -I $(PONYRT_COMMON) \ -g -rdynamic -mcx16 test.c libclib.a $(PONYRT_LIB) -lpthread -ldl
  The C code needs to call
  pony_init to initialize the Pony runtime. It gets passed the standard C
  argc and
  argv arguments that
  main receives so it can handle any Pony runtime specific switches. After this any Pony actors can be allocated and methods or behaviours called on them. The order for actor creation is to call the
  _Alloc function to allocate the memory for the actor and then the constructor method. Pony names the constructor method based on the name in the Pony code with
  __send appended.
  Actors are asynchronous so just like in Pony code behaviours aren't run immediately. They are queued for execution and will run when the scheduler is started. This is what
  pony_start does. The arguments passed to
  pony_start are a boolean indicating whether to block until all Pony actors have completed (by passing a false value) or to return immediately (by passing a true value). If the latter is done then the scheduler runs asynchronously. It can be stopped with a later call to
  pony_stop. The second parameter indicates whether to initialize Pony specific parts of the runtime (sockets and serialization). It's possible to continue calling Pony functions after the
  pony_start and before
  pony_stop. For example:
  pony_init(argc, argv); Foo* x = Foo_Alloc(); Foo_tag_hi_o__send(x); Foo_tag_create_o__send(x); pony_start(true, true); Foo* y = Foo_Alloc(); Foo_tag_hi_o__send(y); Foo_tag_create_o__send(y); pony_stop();
  In this snippet another actor is created after
  pony_start and behaviours are called on it. These are queued and run as expected.
  pony_stop blocks until all Pony actors have completed.
  There are other Pony runtime functions in
  pony.h that allow allocating memory on the current actor heap, unscheduling an actor so that no behaviours will be run until rescheduled, making a C thread 'become' an actor so it can call Pony runtime functions, poll for messages on an unscheduled actor, etc. It's possible to allocate an actor, unschedule it, and then use a C thread to handle its message queue using
  pony_become. When you aren't handling messages to the unscheduled actor you can call functions to it from C with no race conditions.
  None of this is currently documented and it will probably change as usage develops. In the meantime it's a useful feature for using Pony functionality in existing applications.