Pregunta

En este momento estoy trabajando en un lenguaje de secuencias de comandos que aún no tiene un FFI. Me gustaría saber cuál es la forma más conveniente de hacerlo, suponiendo que me gustaría escribirlo como lo hacen los geeks geniales: me gustaría escribir el FFI en el lenguaje de secuencias de comandos en sí.

El lenguaje de programación que necesito para interactuar es C. Entonces, para lo básico, sé que libdl.so es mi mejor amigo. Obviamente, no es lo único que voy a necesitar, sino lo más importante de ellos.

Solo tengo pequeñas ideas sobre qué más necesito para ello. Me gustaría obtener un comportamiento similar del FFI que tiene Python Ctypes.

¿Qué debo saber para llegar tan lejos? Sé que hay algo de magia seria con las estructuras de datos con las que necesitaré lidiar. ¿Cómo lo manejo para poder hacer la mayor parte de esa magia seria en el lenguaje de secuencias de comandos en sí? Habría usado de tal magia para mucho más que la interfaz de función extranjera. Por ejemplo, es posible que desee pasar datos binarios tipo C a los archivos.

¿Fue útil?

Solución

Creo que una respuesta apropiada requiere una ensayo detallado.

Básicamente, debe haber envoltorios para la carga de la biblioteca y las instalaciones de búsqueda de símbolos proporcionadas por el sistema operativo host. Si los tipos de datos principales de su idioma se representan internamente con una sola estructura de datos C, entonces se puede colocar un requisito en los desarrolladores de la biblioteca de que los parámetros y el tipo de retorno de las funciones C exportadas deben ser objetos de esa estructura de datos. Esto hará que el intercambio de datos sea más fácil de implementar. Si su lenguaje tiene alguna forma de expresiones de patrones y funciones de primera clase, entonces la firma de las funciones C podría escribirse en patrones y la biblioteca buscó una función que coincida con una firma equivalente. Aquí hay algún pseudocódigo de una función C y su uso en el script:

/* arith.dll */
/* A sample C function callable from the scripting language. */

#include "my_script.h" // Data structures used by the script interpreter.

My_Script_Object* add(My_Script_Object* num1, My_Script_Object* num2)
{
   int a = My_Script_Object_To_Int(num1);
   int b = My_Script_Object_To_Int(num2);
   return Int_To_My_Script_Object(a + b);
}

/* End of arith.dll */

// Script using the dll
clib = open_library("arith.dll");

// if it has first-class functions
add_func = clib.find([add int int]);
if (cfunc != null)
{
   sum = add_func(10, 20);
   print(sum);
}

// otherwise
print(clib.call("add", 10 20));

No es posible discutir más detalles de implementación aquí. Tenga en cuenta que no hemos dicho nada sobre la recolección de basura, etc.

Las fuentes disponibles en los siguientes enlaces pueden ayudarlo a avanzar aún más:

http://common-lisp.net/project/cffi/ http://www.nongnu.org/cinvoke/

Otros consejos

Verificar http://sourceware.org/libffi/

Recuerde que las convenciones de llamadas serán diferentes en diferentes arquitecturas, es decir, qué variables de función de pedido se encuentran en la pila. No sé sobre escribirlo en su propio lenguaje de secuencias de comandos, sí sé que Java JNI usa libffi.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top