C <-> Erlang with IC
Torbjorn Tornkvist
tobbe@REDACTED
Thu Aug 19 16:12:29 CEST 1999
> I am trying to export some C functions to Erlang and at the same time getting
> those C functions to invoke Erlang functions in the same program. Like that
> of the calback functions. How can this be done in IC ?? if possible at all...
Sorry, I know I shouldn't promote IG (since it is obsolete) but
I can't help myself. Actually I would also be interested in how
you would do it with IC. Anyway, here is how you do it with IG:
example.h
--------------------------------------------------------------
#ifndef _EXAMPLE_H
#define _EXAMPLE_H
#include <stdio.h>
#ifdef HIDE
/*
* C functions we want to call from Erlang
*/
IG_fun FILE *fopen(IG_string path, IG_string mode);
IG_fun int fclose( FILE *);
#endif
#endif
--------------------------------------------------------------
Run this through IG:
erl-shell> ig:gen(example).
Compile the result:
gcc -ansi -pedantic -Wall \
-I /usr/local/lib/erlang/usr/include \
-L /usr/local/lib/erlang/usr/lib \
-o example example_stub.c \
/usr/local/lib/erlang/usr/lib/igio.o \
/usr/local/lib/erlang/usr/lib/igmain.o -lerl_interface
erlc example.erl
Now you can call those functions from Erlang:
--------------------------------------------------------------
23:57 ~/junk> ls
example* example.beam example.erl example.h example_stub.c
23:57 ~/junk> erl
Erlang (BEAM) emulator version 47.4.1
Eshell V47.4.1 (abort with ^G)
1> S=example:start().
<0.30.0>
2> {ok,Fd} = example:fopen(S,"TOUCH_ME","wb").
{ok,134618608}
3> example:fclose(S,Fd).
{ok,0}
4>
BREAK: (a)bort (c)ontinue (p)roc info (i)nfo (l)oaded
(v)ersion (k)ill (D)b-tables (d)istribution
a
23:58 ~/junk> ls
TOUCH_ME example* example.beam example.erl example.h example_stub.c
23:58 ~/junk>
--------------------------------------------------------------
To call an Erlang function from C is a bit more complicated,
but basically: add the following to example.h:
--------------------------------------------------------------
/*
* Erlang function we want to call from C
*/
typedef struct { /* First a data type to store */
int hour; /* the result from erlang:time/0 */
int minute;
int second;
} etime;
IG_call etime get_etime(void);
--------------------------------------------------------------
Run IG again. This time you will also get an 'example.hrl' out
from IG. As per default, IG will assume you are implementing
your callback Erlang functions in example_cb.erl, so create
this file:
--------------------------------------------------------------
-module(example_cb).
-export([get_etime/1]).
-include("example.hrl").
get_etime(_Pid) ->
{H,M,S} = time(),
#etime{hour = H, minute = M, second = S}.
--------------------------------------------------------------
The hardest part is to write a C program that can trigger
this code. I leave this as an exercise for you... ;-)
Cheers /Tobbe
More information about the erlang-questions
mailing list