1

我想为 C 库(SOIL)生成一个通用的 lisp cffi 包装器,虽然我对 cl 和 cffi 很有信心,但我不确定要使用哪些库或如何开始使用它们。基本上我会问一个更详细的问题,但不知道我不知道什么。

4

1 回答 1

3

[更新] 这已经过时了。这些天我建议研究cl-autowrapcffi/c2ffi


那里有一些包装器生成器,但有两个名称从该组中脱颖而出,SWIG 和 Verrazano


Verrazano 现在没有维护,所以真的不应该依赖,但是对于你使用 SOIL 库,它可以工作......有点!以下步骤直接取自使用 kinect 和 common lisp的示例。

首先,确保您已安装 gcxml。对我来说,这是按如下方式完成的:

sudo apt-get install gccxml

现在在您的 repl 中(您可能必须根据您的系统编辑路径):

(ql:quickload :cffi)
(ql:quickload :verrazano)
(verrazano:generate-binding (list :cffi :package-name :soil :input-files (list "SOIL/SOIL.h")))

您现在在 soil.lisp 文件中有一个包装器。我马上就发现了问题,枚举的命名非常奇怪(.-1 .-2 等),并且这些相同的奇怪名称正在被导出。我删除了这些并重命名了枚举。然后您会发现函数调用中没有使用枚举,因此您需要修改“defcfun”调用以使用它们。

如果您不习惯这样做,我建议您找到一个已经完成此操作的库作为指南。我发现 lispbuilder 在这方面有一些广泛的例子。


SWIG 绝对是更好的选择,即使使用复杂的库也能很好地为您服务。一般的做法是编写一个 SWIG 接口文件,它告诉 swig 在哪里可以找到库以及要包装哪些功能。SWIG 的文档非常广泛且非常好:

http://www.swig.org/Doc2.0/Contents.html#Contents

还可以查看他们关于 Swig 和 Common Lisp 的页面http://www.swig.org/Doc2.0/Lisp.html

现在最好使用单独的接口文件,原因如下(取自 swig 文档)

  • 很少需要访问大包中的每个函数。许多 C 函数在脚本环境中可能很少或根本没有用处。因此,为什么要包装它们?
  • 单独的接口文件提供了提供有关如何构造接口的更精确规则的机会。
  • 接口文件可以提供更多的结构和组织。
  • SWIG 无法解析出现在头文件中的某些定义。拥有一个单独的文件可以让您消除或解决这些问题。
  • 接口文件对接口是什么提供了更精确的定义。想要扩展系统的用户可以转到接口文件并立即查看可用的内容,而无需从头文件中挖掘出来。

...但是,您通常可以不写任何内容就离开,让 SWIG 解决。对于土壤,这涉及以下内容:

编写一个名为 soil.i 的文件并将以下内容放入其中(您可能需要更改路径)。

%module soil
%{
/* Includes the header in the wrapper code */
#include "/usr/include/SOIL/SOIL.h"
%}

/* Parse the header file to generate wrappers */
%include "/usr/include/SOIL/SOIL.h"

接下来在终端 swig -cffi -module soil soil.i 运行以下命令

您将拥有一个新的 soil.lisp 文件。与 verrazano 一样,请查看函数调用以查看枚举是如何使用的(或者更有可能不使用)。


现在有了这两个,你几乎肯定想让事情变得更“口齿不清”。通常有一些指针传递给要由 C 函数填充的函数,您希望对用户隐藏这些指针。

这是一个开始的地方,希望你可以从这里开始工作。再见

于 2013-07-09T08:33:47.723 回答