add C API documentation
This commit is contained in:
parent
7ce095b7ae
commit
447a05f7c3
|
@ -0,0 +1,96 @@
|
||||||
|
C API
|
||||||
|
=====
|
||||||
|
|
||||||
|
You can write Picrin's extension by yourself from both sides of C and Scheme. This page describes the way to control the interpreter from the C world.
|
||||||
|
|
||||||
|
Extension Library
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
If you want to create a contribution library with C, the only thing you need to do is make a directory under contrib/. Below is a sample code of extension library.
|
||||||
|
|
||||||
|
* contrib/add/CMakeLists.txt::
|
||||||
|
|
||||||
|
list(APPEND PICRIN_CONTRIB_INITS "void pic_init_add(pic_state *)\; pic_init_add(pic)\;")
|
||||||
|
list(APPEND PICRIN_CONTRIB_SOURCES ${PROJECT_SOURCE_DIR}/contrib/add/add.c)
|
||||||
|
|
||||||
|
* contrib/add/add.c::
|
||||||
|
|
||||||
|
#include "picrin.h"
|
||||||
|
|
||||||
|
static pic_value
|
||||||
|
pic_add(pic_state *pic)
|
||||||
|
{
|
||||||
|
double a, b;
|
||||||
|
|
||||||
|
pic_get_args(pic, "ff", &a, &b);
|
||||||
|
|
||||||
|
return pic_float_value(a + b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pic_init_add(pic_state *pic)
|
||||||
|
{
|
||||||
|
pic_deflibrary ("(picrin add)") {
|
||||||
|
pic_defun(pic, "add", pic_add);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
After recompiling the interpreter, the library "(picrin add)" is available in the REPL, which library provides a funciton "add".
|
||||||
|
|
||||||
|
User-data vs GC
|
||||||
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
When you use dynamic memory allocation inside C APIs, you must be caseful about Picrin's GC. Fortunately, we provides a set of wrapper functions for complete abstraction of GC. In the case below, the memory (de)allocators *create_foo* and *finalize_foo* are wrapped in pic_data object, so that when an instance of foo losts all references from others to it picrin can automatically finalize the orphan object::
|
||||||
|
|
||||||
|
/** foo.c **/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "picrin.h"
|
||||||
|
#include "picrin/data.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* C-side API
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct foo {
|
||||||
|
// blah blah blah
|
||||||
|
};
|
||||||
|
|
||||||
|
struct foo *
|
||||||
|
create_foo ()
|
||||||
|
{
|
||||||
|
return malloc(sizeof(struct foo));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
finalize_foo (void *foo) {
|
||||||
|
struct foo *f = foo;
|
||||||
|
free(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* picrin-side FFI interface
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const pic_data_type foo_type = { "foo", finalize_foo };
|
||||||
|
|
||||||
|
static pic_value
|
||||||
|
pic_create_foo(pic_state *pic)
|
||||||
|
{
|
||||||
|
struct foo *f;
|
||||||
|
struct pic_data *dat;
|
||||||
|
|
||||||
|
pic_get_args(pic, ""); // no args here
|
||||||
|
|
||||||
|
f = create_foo();
|
||||||
|
|
||||||
|
data = pic_data_alloc(pic, &f, md);
|
||||||
|
|
||||||
|
return pic_obj_value(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
pic_init_my_data(pic_state *pic)
|
||||||
|
{
|
||||||
|
pic_defun(pic, "create-my-data", pic_create_foo); // (create-foo)
|
||||||
|
}
|
|
@ -15,6 +15,7 @@ Contents:
|
||||||
deploy.rst
|
deploy.rst
|
||||||
lang.rst
|
lang.rst
|
||||||
libs.rst
|
libs.rst
|
||||||
|
capi.rst
|
||||||
|
|
||||||
Indices and tables
|
Indices and tables
|
||||||
==================
|
==================
|
||||||
|
|
Loading…
Reference in New Issue