Ur C FFI Example

From Impredicative Wiki
(Difference between revisions)
Jump to: navigation, search
(Revert defacement)
(5 intermediate revisions by 5 users not shown)

Latest revision as of 11: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.


[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]}

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

Personal tools