我正在尝试将camlidl
与C库一起使用以生成OCaml绑定。该库使用“不透明的结构”方法来保持对象状态:所有函数都采用或提供了指向该结构的指针,这意味着我的代码对其不可见。该库的.h文件包含以下内容:
typedef struct opaque_struct opaque_struct;
opaque_struct * create_opaque_struct;
int do_x_with_opaque_struct(int, opaque struct *);
void destroy_opaque_struct(opaque struct *);
,因此我希望永远不要直接使用该结构,而要在任何地方使用指向它的指针。
不幸的是,我在camlidl
手册中找不到如何正确执行此操作的方法。我检查了以下部分:
3.5结构
这对我没有用-我正在处理一个不完整的结构定义,并且不希望/不能使用对caml对象的任何翻译。
3.2指针
似乎总是在所有地方使用[ptr] struct opaque_struct *
应该可行。但这有一个缺点:destroy_opaque_struct(opaque_struct * x)
在对象超出范围并发生GC时不会自动调用。这迫使OCaml用户自己管理引用。
3.8类型定义
虽然这会给我[finalize(destroy_opaque_struct)]
像我想要的GC一样,但我不能使用typedef,因为它会生成损坏的代码。我独自尝试过typedef [abstract] struct opaque_struct opaque_struct
。这样会生成不起作用的c2ml和ml2c例程:它们试图为不完整的类型进行指针分配,这根本不起作用。
那么解决这个问题的正确方法是什么?这似乎是一个足够普遍的用例,我想camlidl应该支持它,但是我缺少了一些东西。
编辑:一些游戏,我发现了一种方法。考虑包含以下内容的test.idl:
quote(c, "void camlidl_destroy_opaque_struct(opaque_struct * x) { destroy_opaque_struct(x); }");
typedef [abstract,finalize(camlidl_destroy_opaque_struct),ml2c(dummy),c2ml(dummy)] struct opaque_struct opaque_struct;
[ptr] * opaque_struct create_opaque_struct();
int do_x_with_opaque_struct([in] int int_param, [in,ptr] opaque_struct * struct_param);
这将为ml_c和c2ml帮助器生成一个带有“虚拟” #define设置的_stubs.c,如下所示:
...
void camlidl_destroy_opaque_struct(opaque_struct * x) {
destroy_opaque_struct(x); }
#define camlidl_ml2c_test_opaque_struct(v,c,ctx) dummy(v,c)
#define camlidl_c2ml_test_opaque_struct(c,ctx) dummy(c)
value camlidl_test_create_opaque_struct(value _unit)
{
...
由于我从未真正直接使用过opaque_struct,因此从未真正调用过c2ml和ml2c,因此可以确定它们不存在。
但是,MAN这样做似乎是一种粗略的方法!我可能会提交一个pull req来添加一个特殊情况参数,这样,如果您将其标记为 void (例如c2ml(void)
),它将完全省略创建c2ml或ml2c函数的操作。它似乎仍然像黑客一样,应该有一种更好的支持方式。有想法吗?
答案 0 :(得分:0)
我最终确实通过电子邮件向Xavier Leroy(项目维护者)发送了电子邮件,这是他的回复。
我会尽力帮助您,但作为回复的序言:
camlidl是我在1990年代后期开发的一个旧项目, 从那时起,除了确保它仍然 使用最新的OCaml版本进行编译。一些项目仍在使用 camlidl,尤其是在Microsoft,但最近的项目往往会 请改用Ctypes(https://github.com/ocamllabs/ocaml-ctypes)。一世 不建议您将camlidl用于新项目。
现在回答您的问题:以下方法应该起作用
quote(C, "#include <lib.h>") quote(C, "void t_final (t * x) { destroy_opaque_struct (*x); }") typedef [abstract,finalize(t_final)] struct opaque_struct * t;
假设lib.h包含
typedef struct opaque_struct opaque_struct; opaque_struct * create_opaque_struct; int do_x_with_opaque_struct(int, opaque_struct *); void destroy_opaque_struct(opaque_struct *);
令人困惑的是
typedef opaque_struct * t
被拒绝了 因为CamlIDL不知道类型opaque_struct
。但是 未知结构没有问题...