是否可以使用Fiddle传递结构或将结构返回到本机代码?

我想使用Fiddle访问从Rust代码编译的本机库。 结构的C表示非常简单,它只是一个指针和一个长度:

typedef struct { char *data; size_t len; } my_thing_t; // Example function that somehow accepts a struct void accepts_a_struct(my_thing_t thing); // Example function that somehow returns a struct my_thing_t returns_a_struct(void); 

但是,我可以找到的所有示例都接受或返回指向结构的指针,而不是结构本身。 如果可能的话,我想避免双重间接。

我借用了Fiddle::Importer文档中的一个例子。 但是,我没有看到如何使用结构而不是指向结构的指针正确调用extern方法:

 require 'fiddle' require 'fiddle/import' module LibSum extend Fiddle::Importer dlload './libsum.so' extern 'double sum(double*, int)' extern 'double split(double)' end 

注意

小提琴与FFIgem不同 。 Fiddle是Ruby标准库的一个组件,不作为单独的gem提供。 这些相关问题涉及FFIgem,而不是Fiddle:

  • 如何在以结构为参数的Ruby FFI方法中包装函数?
  • 如何在RubyFFI中将结构指定为函数的返回值?

我已经阅读了Fiddle文档,因为我可以看到它是不可能的,因为即使在核心函数定义Fiddle::Function.new它需要Fiddle::CParser可以处理的args。 我已经做了各种测试并使其工作我必须将您的代码转换为这样的代码:

test2.c中

 #include  #include  typedef struct { char *data; char *more_data; size_t len; } my_thing_t; my_thing_t *returns_a_struct(void){ my_thing_t *structure = malloc(sizeof(my_thing_t)); structure->data = "test2"; structure->more_data = "I am more data"; structure->len = 5; return structure; }; 

IRB

 require 'fiddle' require 'fiddle/import' module Testmd extend Fiddle::Importer dlload './test2.dll' RetStruct = struct ['char *data','char *more_data','size_t len'] extern 'RetStruct* returns_a_struct(void)' end include Testmd 2.2.1 :013 > res = Testmd::returns_a_struct(nil) => # 2.2.1 :014 > s = RetStruct.new(res) => #> 2.2.1 :015 > s.data.to_s => "test2" 2.2.1 :016 > s.more_data.to_s => "I am more data" 2.2.1 :017 > s.len => 5 

我得到的是, Fiddle可以使用简单类型操作,但需要使用引用传递structunion类型。 它还有这个类的包装器。 这些包装器也是从Fiddle::Pointerinheritance而来的,这导致我们得出结论,他们希望我们使用这些数据类型的指针。

如果您想了解更多有关此内容的详细信息,或者您想添加此function,可以通过他们的git repo进行操作 。