是否可以使用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
可以使用简单类型操作,但需要使用引用传递struct
和union
类型。 它还有这个类的包装器。 这些包装器也是从Fiddle::Pointer
inheritance而来的,这导致我们得出结论,他们希望我们使用这些数据类型的指针。
如果您想了解更多有关此内容的详细信息,或者您想添加此function,可以通过他们的git repo进行操作 。
- 用户has_many:用户,:通过=>:朋友 – 怎么样?
- 对于Ruby on Rails,当使用Webrick时,它是否支持并发请求和Keep-Alive,以及为什么加载.js和.png文件这么慢?