我想使用 Fiddle访问从 Rust 代码编译的 native 库。该结构的 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
documentation 中借用了一个例子.但是,我看不到如何使用结构而不是指向结构的指针正确调用 extern
方法:
require 'fiddle'
require 'fiddle/import'
module LibSum
extend Fiddle::Importer
dlload './libsum.so'
extern 'double sum(double*, int)'
extern 'double split(double)'
end
注意
Fiddle 与 FFI gem 不相同. Fiddle 是 Ruby 标准库的一个组件,不作为单独的 gem 提供。这些相关问题指的是 FFI gem,而不是 Fiddle:
最佳答案
我已经浏览了 Fiddle 文档,正如我所见,这是不可能的,因为即使在核心函数定义 Fiddle::Function.new
中,它也需要 Fiddle::CParser< 的参数
可以处理。我已经进行了各种测试,为了使其正常工作,我必须将您的代码转换为如下内容:
测试2.c
#include <stdio.h>
#include <stdlib.h>
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)
=> #<Fiddle::Pointer:0x00000000b12a10 ptr=0x00000000e066b0 size=0 free=0x00000000000000>
2.2.1 :014 > s = RetStruct.new(res)
=> #<Testmd::RetStruct:0x00000000c3e9e8 @entity=#<Fiddle::CStructEntity:0x000000007f0ad0 ptr=0x00000000e066b0 size=24 free=0x00000000000000>>
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
继承的,这让我们得出结论,他们希望我们对这些数据类型使用指针。
如果您想了解有关此的更多详细信息或想要添加此功能,您可以访问 their git repo .
关于ruby - 是否可以使用 Fiddle 将结构传递或返回到 native 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30293406/