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