Ruby FFI回调返回值

用户名

我正在努力让我了解红宝石FFI。没有办法利用FFI回调的返回值吗?

这是我的最小示例:

require 'ffi'

class Foo
  extend FFI::Library
  ffi_lib File.expand_path('fun.o')
  callback :incoming_rpc, [:string], :string
  attach_function :do_some_work, [:incoming_rpc, :string], :string, blocking: true

  def initialize
    @callback = build_callback_runner
    output = do_some_work(@callback, "Ruby init...")
    puts "Output: #{output.inspect}"
  end

  def build_callback_runner
    FFI::Function.new(:string, [:string]) do |name|
      puts "Inside runner: #{name}"
      "DO YOU READ ME?"
    end
  end

end

Foo.new

这是我正在调用的C函数:是的,我知道它不是出色的C,我的原始接收器正在运行中,它也以完全相同的方式失败。(我也不保证会写出精彩的作品)

// Name: fun.c
// Compiled with: gcc -shared -o fun.o fun.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef char* (*callbkfn)(char*);

extern char* do_some_work(callbkfn fn, char* name);

char* do_some_work(callbkfn fn, char* userdata) {
  printf("do_some_work param: %s\n", userdata);
  printf("callback output: %s\n", fn(strdup("Hello from C")));
  return strdup("Returned from C");
}

输出:

do_some_work param: Ruby init...
Inside runner: Hello from C
callback output: (null)
Output: "Returned from C"

回调输出中的null似乎无法动摇。如何将回调FFI :: Function或回调proc的“返回”值传递回C?FFI文档似乎总是将callback设置为:void,我猜答案在指针页面上的某处-但是我在绘制空白(很像我的回调)

马特

如果使用a:pointer作为返回类型而不是:stringchar无论如何只是一个指针),就可以使它起作用

class Foo
  extend FFI::Library
  ffi_lib File.expand_path('fun.o')
  callback :incoming_rpc, [:string], :pointer # <- change here
  attach_function :do_some_work, [:incoming_rpc, :string], :string, blocking: true

  def initialize
    @callback = build_callback_runner
    output = do_some_work(@callback, "Ruby init...")
    puts "Output: #{output.inspect}"
  end

  def build_callback_runner
    FFI::Function.new(:pointer, [:string]) do |name|  # <- and here
      puts "Inside runner: #{name}"
      FFI::MemoryPointer.from_string("DO YOU READ ME?") # <- and here
    end
  end

end

Foo.new

使用问题中的C代码,将产生:

do_some_work param: Ruby init...
Inside runner: Hello from C
callback output: DO YOU READ ME?
Output: "Returned from C"

主要问题是内存分配和释放。在这种情况下MemoryPointer,将进行垃圾回收,这将释放字符串数据。我相当确定这是安全的,只要C函数不保存指针并在以后尝试使用它即可(即GC不会在C函数完成之前发生)。如果是这样,您将需要确保该函数复制了该字符串,或者研究了包装和使用mallocandfree

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Ruby:从键值对返回值

来自分类Dev

返回值未在Ruby中提取

来自分类Dev

ruby中的require语句的返回值

来自分类Dev

从Ruby中的嵌套哈希返回值

来自分类Dev

Ruby:获取python脚本的返回值

来自分类Dev

从Python中的回调返回值

来自分类Dev

在回调中使用返回值

来自分类Dev

Scala-回调的返回值

来自分类Dev

从映射中的回调返回值

来自分类Dev

Javascript,从回调返回值

来自分类Dev

回调,JavaScript返回值

来自分类Dev

如何用“#=>”之类的注释掉我的Ruby返回值?

来自分类Dev

Ruby-Array.find,但返回值块

来自分类Dev

我可以在Ruby的“确保”中获取返回值吗?

来自分类Dev

Ruby,如何控制调用实例对象的返回值

来自分类Dev

在方法中返回值的Rails中搜索ruby

来自分类Dev

在Ruby中有多个返回值的函数的条件赋值?

来自分类Dev

Ruby中的隐式返回值范围

来自分类Dev

如何用“#=>”之类的注释掉我的Ruby返回值?

来自分类Dev

命令行 / IRB 不会返回值 - Ruby

来自分类Dev

在回调Angular JS指令中获取返回值

来自分类Dev

消息回调很少返回值-Chrome扩展程序

来自分类Dev

南希路线-回调返回值

来自分类Dev

从Meteor.method中的回调返回值

来自分类Dev

PHP回调MySQL从不返回值

来自分类Dev

带参数和返回值的JavaScript回调

来自分类Dev

NodeJS获得异步返回值(回调)

来自分类Dev

是否可以从promise通知回调中返回值?

来自分类Dev

如何从函数内的回调返回值?