实现外部函数接口的指南

3

我现在正在开发一种脚本语言,它还没有 FFI。我想知道最方便的方法是什么,假设我想像酷炫的极客一样编写 FFI - 我想用脚本语言自身编写 FFI。

我需要与之接口的编程语言是 C。所以对于基础知识,我知道 libdl.so 是我的好朋友。显然,这不是我唯一需要的东西,但最重要的东西。

我只有一点关于我还需要什么的想法。我想获得与 python ctypes 相似的 FFI 行为。

为了达到这个目的,我需要知道些什么?我知道我需要处理一些严肃的数据结构魔法。如何管理它,以便我可以在脚本语言本身中完成大部分严肃的魔法?我将从这样的魔法中获益很多,不仅限于外来函数接口。例如,我可能想将类似 C 的二进制数据传递给文件。

2个回答

3
我认为一个合适的答案需要详细的文章
基本上,应该有包装器来提供主机操作系统提供的库加载和符号搜索功能。如果您的语言的核心数据类型是使用单个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/


谢谢。尽管所描述的东西可能最简单,但也会强制我写 C 部分到绑定中。我认为这不符合我的需求。 - Cheery
这个问题中发布的链接现在似乎已经失效了,为什么会这样? - Anderson Green

1

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

请记住,不同架构的调用约定可能会有所不同,即函数变量弹出到堆栈上的顺序。我不知道是否可以使用自己的脚本语言编写它,但我知道Java JNI使用libffi。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接