2010-08-19 28 views

Respuesta

6

El enfoque más reciente consideraría los NIF http://www.erlang.org/doc/man/erl_nif.html (tenga cuidado, puede bloquear la VM). manera regular para hacer que implica ligado en los conductores (google el enlace, porque anti-spam mantiene)

+3

NIF son algo que probablemente quiera evitar a menos que * realmente * sepa lo que está haciendo. Si llamas a algo que bloquea, has volado el programador de Erlang. Si llamas a algo que se cuelga, tu antiguamente robusto Erlang va a estallar. –

21

Esto es para crear un controlador

En primer lugar usted necesita para crear la C/C++ Files que hacer eso.

Tendrán que incluir

#include "erl_driver.h" 
#include "ei.h" 

A continuación, tendrá que configurar la asignación de controladores

/* mapping of the drivers functions */ 
static ErlDrvEntry driver_entry = { 
    NULL,        /* init */ 
    startup_function_name,   /* startup */ 
    shutdown_function_name,   /* shutdown */ 
    NULL,        /* output */ 
    NULL,        /* ready_input */ 
    NULL,        /* ready_output */ 
    driver_name,      /* the name of the driver */ 
    NULL,        /* finish */ 
    NULL,        /* handle */ 
    NULL,        /* control */ 
    NULL,        /* timeout */ 
    outputv_function_name,   /* outputv */ 
    NULL,        /* ready_async */ 
    NULL,        /* flush */ 
    NULL,        /* call */ 
    NULL,        /* event */ 
    ERL_DRV_EXTENDED_MARKER,   /* ERL_DRV_EXTENDED_MARKER */ 
    ERL_DRV_EXTENDED_MAJOR_VERSION, /* ERL_DRV_EXTENDED_MAJOR_VERSION */ 
    ERL_DRV_EXTENDED_MAJOR_VERSION, /* ERL_DRV_EXTENDED_MINOR_VERSION */ 
    ERL_DRV_FLAG_USE_PORT_LOCKING  /* ERL_DRV_FLAGs */ 
}; 

DRIVER_INIT(driver_name){ 
    return &driver_entry; 
} 

Nota: si está intentando ejecutar código C++ en lugar de C se le necesitará

extern "C" { 
    DRIVER_INIT(driver_name){ 
    return &driver_entry; 
    } 
} 

Y tendrá que lanzar cualquier cadena literal con (char *)

entonces es bueno para definir una estructura que va a contener la información de los puertos

typedef struct 
{ 
    ErlDrvPort port; 
} port_data; 

Por último, tendrá que configurar todas las funciones

static ErlDrvData startup_function_name(ErlDrvPort port, char *doc) 
{ 
    /* Plus any other start up methods you need */ 
    port_data* d = (port_data*)driver_alloc(sizeof(port_data)); 
    d->port = port; 
    return (ErlDrvData)d; 
} 

/* Plus any other shutdown methods you need */ 
static void shutdown_function_name(ErlDrvData handle) 
{ 
    driver_free((char*)handle); 
} 

static void outputv_function_name(ErlDrvData handle, ErlIOVec *ev) 
{ 
    port_data* d = (port_data*)handle; 
    char* inputstring = ev->binv[1]->orig_bytes; 
    ErlDrvTermData spec[] = { 
     ERL_DRV_ATOM, driver_mk_atom("ok"), 
     ERL_DRV_BUF2BINARY, inputstring, strlen(inputstring) 
     ERL_DRV_TUPLE, 2 
    }; 
    driver_send_term(d->port,driver_caller(d->port),spec,sizeof(spec)/sizeof(spec[0])); 
} 

usted querrá compilar este C/C++ de código en un objeto compartido y vincularlo con la interfaz ERL

g++ -fpic -rdynamic -shared file_name -lerl_interface -lei 

Ahora de Erlang que querrá hacer un par de cosas: Tendrá que cargar el controlador

erl_ddll:load_driver("./location/of/driver", driver_name). 

A continuación, vamos a abrir un puerto para el conductor

Port = open_port({spawn, driver_name}, [binary]). 

Y, por último, usted puede enviar datos al puerto

port_command(Port, <<"String to Echo Back"), 
receive 
    {ok, String} -> io:format("Received ~p back from the driver") 
end. 
+2

¿Por qué este tipo no recibió más votos? – BAR

Cuestiones relacionadas