ruby - 是否可以使用 Fiddle 将结构传递或返回到 native 代码?

标签 ruby ffi

我想使用 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 可以使用简单类型进行操作,但需要使用引用传递 structunion 类型。它仍然有这个类的包装器。此外,这些包装器是从 Fiddle::Pointer 继承的,这让我们得出结论,他们希望我们对这些数据类型使用指针。

如果您想了解有关此的更多详细信息或想要添加此功能,您可以访问 their git repo .

关于ruby - 是否可以使用 Fiddle 将结构传递或返回到 native 代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30293406/

相关文章:

ios - 将静态库(Rust .a)导入到 iOS 中的 Flutter 项目

c++ - Ocamlopt 不产生任何输出,只有一个错误代码

ruby - 寻找最小的质因数

ruby-on-rails - 在 Rails 4 中,如何根据今天的日期显示数据库中的信息?

ruby - 如何确定 jRuby 兼容的确切 ruby​​ 版本

objective-c - 在 Ruby 中通过 FFI 调用 Objective-C 选择器方法

ruby - 实现 gem ruby rake 测试的最新技术/最佳实践是什么?

ruby - 多线程 ruby​​ 程序只使用 100% cpu

haskell - 使用 FFI 声明时的 GHCi 运行时链接器问题

c# - 如何让 Rust FFI 返回结构数组或更新内存?