Ir al contenido principal

This is my blog, more about me at marianoguerra.github.io

🦋 @marianoguerra.org 🐘 @marianoguerra@hachyderm.io 🐦 @warianoguerra

evaluando python desde erlang

y el secreto se develo, como tener algo como eval de python pero corriendolo desde erlang.

el codigo no es lo mas bonito de la tierra pero ya va a ir mejorando.

primero que todo bajate erlang R13B04 para tener la ultima version de la API de NIF.

crea un archivo pynerl.c

/* pynerl.c */
#include <stdio.h>
#include "erl_nif.h"
#include <Python.h>

#define STR_SIZE 1024
char code[STR_SIZE];

static ERL_NIF_TERM pyeval(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
Py_Initialize();

if (enif_get_string(env, argv[0], code, STR_SIZE, ERL_NIF_LATIN1) < 0) {
return enif_make_string(env, "code too long", ERL_NIF_LATIN1);
}
else {
PyRun_SimpleString(code);
}

Py_Finalize();

return argv[0];
}
static ErlNifFunc nif_funcs[] =
{
{"pyeval", 1, pyeval}
};

ERL_NIF_INIT(pynerl,nif_funcs,NULL,NULL,NULL,NULL)


y uno llamado pynerl.erl

-module(pynerl).
-export([init/0, pyeval/1]).

-on_load(init/0).

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

pyeval(_Str) ->
"NIF library not loaded".


despues compila ambos:


gcc -fPIC -shared -o pynerl.so pynerl.c -I $ERL_INCLUDE -I/usr/include/python3.1/ -D_THREAD_SAFE -lpthread -ldl -lutil -lpython3.1 -lm
$ERLC pynerl.erl


en mi caso


$ echo $ERL_INCLUDE
/home/mariano/Software/otp_src_R13B04/erts/emulator/beam
$ echo $ERLC
/home/mariano/Software/otp_src_R13B04/bin/erlc


despues de eso lo probamos


$ $ERL
Erlang R13B04 (erts-5.7.5) [source] [rq:1] [async-threads:0] [kernel-poll:false]

Eshell V5.7.5 (abort with ^G)
1> pynerl:pyeval("print('hello python 3.1 from erlang!')").
hello python 3.1 from erlang!
"print('hello python 3.1 from erlang!')"


observaciones:

uso $ERL porque tengo dos versiones de erlang instalando, esa variable apunta al erlang mas nuevo que tengo compilado.

la primera linea de salida es la ejecucion de la linea, la segunda es el string que le pase como parametro, que es lo que devuelve por ahora pyeval, algun dia va a devolver el objeto que devolvio la evaluacion (mientras sea algo que pueda ser convertido a un tipo de erlang).