实现一个外部函数接口的指南

现在我正在研究一种还没有FFI的脚本语言。 我想知道什么是最简单的方法来实现它,假设我想写它像酷极客 – 我想写在脚本语言本身的FFI。

我需要接口的编程语言是C.所以基本知道libdl.so是我最好的朋友。 显然,这不是我唯一需要的东西,而是最重要的东西。

我只有轻微的想法,我还需要什么。 我想从FFI得到类似于python ctypes的行为。

为了达到这个目的,我需要知道什么? 我知道,我需要处理一些严重的数据结构。 我如何pipe理它,以便我可以在脚本语言本身中完成大部分严重的魔术? 除了外部函数接口之外,我还会使用这种魔法。 例如,我可能想要传递类似C的二进制数据到文件。

我认为一个适当的答案需要一个详细的文章 。

基本上,主机操作系统提供的库加载和符号搜索工具应该是封装的。 如果您的语言的核心数据类型在内部由单个C数据结构表示,那么可以在库开发人员的要求下将导出的C函数的参数和返回类型作为该数据结构的对象。 这将使数据交换更容易实现。 如果你的语言具有某种形式的表达式和第一类函数,那么C函数的签名可能会被写成模式,并且库会搜索与等价签名匹配的函数。 下面是C函数的一些伪代码及其在脚本中的用法:

/* 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)); 

这里不可能讨论更多的实现细节。 请注意,我们没有说垃圾收集等。

以下链接中的可用来源可以帮助您进一步移动:

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

看看http://sourceware.org/libffi/

请记住,调用约定在不同的体系结构上会有所不同,也就是说,哪些顺序函数变量会被弹出到堆栈上。 我不知道用自己的脚本语言编写它,我知道Java JNI使用libffi。