Я пытаюсь разобраться с FFI в ruby. Нет ли способа использовать возврат из обратного вызова 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, мой оригинальный приемник был в go, который также не работает точно так же. (Я не буду обещать, что пишу блестяще go, либо)
// 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"
Это тот ноль в выводе обратного вызова, который я, кажется, не могу трясти. Как вы передаете «возвращаемое» значение обратного вызова FFI :: Function или callback pro c обратно в C? Документация FFI всегда, кажется, устанавливает обратные вызовы как :void
, и я предполагаю, что ответ находится где-то на странице указателей - но я рисую пробел (так же, как мой обратный вызов)