Ur C FFI Example
From Impredicative Wiki
(Difference between revisions)
(vevdiiQpjaWzQYhLaA) |
(Revert defacement) |
Latest revision as of 12:13, 14 January 2010
The Ur C FFI makes it easy to interface with C libraries. Here is a simple example project that uses the FFI. The complete source is available in a tarball.
For a detailed reference, see the manual.
Contents |
[edit] The Library
The following files live in a subdirectory lib of the base directory for our example.
[edit] lib.urs
The central piece of an FFI library is a .urs file declaring the interface of your C code.
val hello : unit -> string (* Returns the string "Hello" *) val important : string -> string (* Adds an exclamation mark at the end of its argument *) val counter : unit -> transaction int (* Every time this is called, it increments a global counter and returns the old value. *)
[edit] lib.h
We need to restate this interface in a way that GCC can understand.
#include <urweb.h> uw_Basis_string uw_Lib_hello(uw_context, uw_unit); uw_Basis_string uw_Lib_important(uw_context, uw_Basis_string); uw_Basis_int uw_Lib_counter(uw_context, uw_unit);
[edit] lib.c
#include <string.h> #include <stdio.h> #include <urweb.h> uw_Basis_string uw_Lib_hello(uw_context ctx, uw_unit u) { return "Hello"; } uw_Basis_string uw_Lib_important(uw_context ctx, uw_Basis_string s) { uw_Basis_string s2 = uw_malloc(ctx, strlen(s)+2); sprintf(s2, "%s!", s); return s2; } static int counter; uw_Basis_int uw_Lib_counter(uw_context ctx, uw_unit u) { return counter++; }
[edit] lib.urp
A project file ties together the whole library.
ffi lib include lib.h link lib.o effectful Lib.counter
[edit] Makefile
CFLAGS := -I/usr/local/include/urweb all: lib.o
[edit] Client Application
Here is one way to use the library we just defined, based out of subdirectory app.
[edit] main.ur
fun counter () = n1 <- Lib.counter (); n2 <- Lib.counter (); return <xml><body> {[n1]}, {[n2]} </body></xml> fun main () = return <xml><body> {[Lib.hello ()]}
{[Lib.important "X"]}
<form> <submit value="Counter fun!" action={counter}/> </form> </body></xml>
[edit] main.urs
val main : unit -> transaction page
[edit] app.urp
library ../lib/lib main