?

Log in

No account? Create an account
entries friends calendar profile Previous Previous
SiDen
sidentdv
sidentdv
Erlang + Ocaml + NIF
В данном посте я хочу привести небольшой пример эрланговской nif на окамле.
Итак, что для начала почитать:
http://www.erlang.org/doc/man/erl_nif.html
http://caml.inria.fr/pub/docs/manual-ocaml/manual032.html

Напишем небольшую функцию sample, результатом которой будет ее единственный аргумент.

На стороне эрланга nif_sample.erl:
-module(nif_sample).

-export([
        init/0,
        sample/1,
        selftest/0
]).

init() ->
        erlang:load_nif("./nif_sample", 0).

sample(_) ->
        throw({error, "NIF library 'nif_sample' not loaded"}).

selftest() ->
        init(),
        sample(sample).


Прослойка на C.
nif_sample.c:
#include <stdio.h>
#include <erl_nif.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>


static ERL_NIF_TERM sample(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
        return ocaml_sample_wrapper(argc, argv);
}

static ErlNifFunc nif_funcs[] =
{
        {"sample", 1, sample}
};

static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
        caml_startup(0);
        return 0;
}

ERL_NIF_INIT(nif_sample, nif_funcs, &load, NULL, NULL, NULL)


ocaml_sample.c:
#include <stdio.h>
#include <string.h>
#include <erl_nif.h>
#include <caml/mlvalues.h>
#include <caml/callback.h>

void* ocaml_sample_wrapper(int argc, const ERL_NIF_TERM argv[])
{
        static value * ocaml_sample = NULL;
        if (ocaml_sample == NULL)
                ocaml_sample = caml_named_value("sample_wrapper");
        return caml_callback(*ocaml_sample, argv[0]);
}


Ну и непосредственно сам окамл sample_wrapper.ml:
let sample_wrapper a =
        a

let _ = Callback.register "sample_wrapper" sample_wrapper


Как все это хозяйство собрать:

ocamlc -custom -output-obj -o sample_wrapper.o sample_wrapper.ml
ocamlc -c -I /usr/local/lib/erlang/usr/include/ ocaml_sample.c
cp /usr/local/lib/ocaml/libcamlrun.a libocamlsample.a
ar r libocamlsample.a sample_wrapper.o ocaml_sample.o
gcc -fPIC -shared -flat_namespace -undefined suppress -o nif_sample.so nif_sample.c -I/usr/local/lib/erlang/usr/include/ -I/usr/local/lib/ocaml/ libocamlsample.a
erlc nif_sample.erl


Что же в конечном итоге вышло:
Erlang R14B02 (erts-5.8.3) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.3  (abort with ^G)
1> nif_sample:selftest().
sample

Tags:

7 comments or Leave a comment
Comments
levgem From: levgem Date: October 1st, 2011 08:45 pm (UTC) (Link)
И чего, это всё реально работает?
sidentdv From: sidentdv Date: October 1st, 2011 08:53 pm (UTC) (Link)
А в чем сомнения?
Если вопрос "работает ли это сейчас на продакшене", то ответ - нет. Как собственно и не вижу причин этому там не работать :)
levgem From: levgem Date: October 2nd, 2011 07:07 am (UTC) (Link)
Нуу. Продакшн тем и отличается от девелопмента, что причин не работать там сходу не видно.
sidentdv From: sidentdv Date: October 2nd, 2011 08:44 am (UTC) (Link)
Суть была поиметь каких-то бенефитов по сравнению с портом(так же на окамле), иксов не получили :) Хотя прирост конечно есть. Поэтому оно и не пошло в продакшн.
alexott From: alexott Date: October 2nd, 2011 08:09 am (UTC) (Link)
дык, Лев Валкин давно говорил, что у них OCaml вместо C
demmonoid From: demmonoid Date: October 2nd, 2011 06:02 am (UTC) (Link)
Вы там батарейки не начали использовать? Че-то без них окамл какой-то не торт :)
sidentdv From: sidentdv Date: October 2nd, 2011 08:46 am (UTC) (Link)
Нет, не начали. Вероятно критическая масса необходимости еще не достигнута :)
7 comments or Leave a comment