Как использовать гем ruby ffi для вызова отдельно стоящей функции в библиотеке ржавчины?
ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-linux]
rustc 0.13.0-nightly (f168c12c5 2014-10-25 20:57:10 +0000)
Я хочу использовать ffi
драгоценный камень в сочетании с rust
,
Я прочитал этот (довольно устаревший) пост в блоге, который показывает, как это сделать.
Проблема в том, что это не работает.
Вот мой код:
test.rs:
fn test(bla: i32) -> i32 { bla*bla }
#[no_mangle]
extern fn _test_wrapper(i: i32) -> i32 {
test(i)
}
test.rb:
require 'ffi'
module Test
extend FFI::Library
ffi_lib File.absolute_path 'libtest.so'
attach_function :_test_wrapper, [:int32], :int32
end
Я собираю test.rs примерно так:
rustc --crate-type dylib test.rs
А потом
ruby test.rb
Выход:
/home/me/.rvm/gems/ruby-2.1.2/gems/ffi-1.9.6/lib/ffi/library.rb:261:in `attach_function': Function '_test_wrapper' not found in [/home/me/Dokumente/ruby/rust_require/specs/test/libtest.so] (FFI::NotFoundError)
from test.rb:7:in `<module:Test>'
from test.rb:3:in `<main>'
Что я делаю не так? (Я уже пытался сделать это pub extern fn
... тоже не работает.)
1 ответ
Вы были близки, вам просто нужно исправить предупреждение, которое вы получите при компиляции кода Rust и сделать функцию общедоступной:
#[no_mangle]
pub extern fn _test_wrapper(i: i32) -> i32 {
test(i)
}
Чтобы помочь мне отладить проблему, я использовал nm
чтобы увидеть, какие символы экспортирует скомпилированная библиотека. Я на OS X, поэтому вам, возможно, придется настроить аргументы и имена файлов:
$ nm -g libtest.dylib
0000000000000e30 T __test_wrapper
0000000000001020 S _rust_metadata_test_04c178c971a6f904
U _rust_stack_exhausted
U dyld_stub_binder
Прежде чем пометить функцию как общедоступную, она не появилась в этом списке.