这是问题Common lisp, CFFI, and instantiating c structs的后续问题,所以基本上这个问题是关于从带有CFFI的Common Lisp传递和返回堆栈上的c函数的c-structs。
上述问题(自2010年起)的答案是,这是不可能的。
当前版本的CFFI支持通过libffi在堆栈上传递和返回结构,如this question中所述。但是,libffi引入了另一个依赖项,而libffi在我所针对的所有系统上进行编译并不容易。因此我不想使用libffi,因为我只有很少的这样的函数可以调用。
正如我所链接的第一个问题所讨论的,可以通过解构结构来调用期望堆栈上的struct参数的c函数。例如,这是一个结构和一个函数定义:
typedef struct
{
int width;
int height;
bool isGreat;
} mystruct;
int do_something(mystruct rect);
可以使用
从Common Lisp调用此函数(cffi:defcfun ("do_something" do-something)
:int
(width :int)
(height :int)
(is-great :boolean))
现在,我有两个问题:
这肯定适用于所有平台吗?我认为在C语言中,根据定义,在这种情况下结构的布局与各个参数完全一致,因此保证可行,但我不确定。
返回结构怎么样?假设有一个C函数
mystruct foo();
是否有可能以不同方式从Common Lisp调用此方法,而不使用libffi,例如:通过告诉CFFI返回结构将占用多少内存,然后解析"手动吗?
答案 0 :(得分:0)
您在此处链接的问题的原始提问者。
我尝试过结构解构技术并取得了不同程度的成功。它似乎在Windows / Linux x86上工作正常,但是我尝试了一些不想合作的库(例如,当它花费/返回地址的结构时,我试图在CFFI中包装libuv)。很多段错误。
然而对于Chipmunk来说,该技术在Windows / Linux上运行良好,具有SBCL,CCL,ECL。但是,Chipmunk结构有两个浮动成员,所以它非常基本。
我总的来说,你的结构越复杂,你要求的麻烦就越多。此外,不确定这将如何移植到非x86平台。
您最好的选择是编写绑定,在您定位的每个平台上尝试它们,看看有什么中断。如果你有时间,另一个选择是编写自己的可移植C包装器,为你处理堆/堆栈的东西。我不喜欢这样,因为它是我的图书馆和用户之间的又一步,但到目前为止(除了花栗鼠和旧版本的libuv),我有幸与C合作需要指针的库。
TL; DR: