我想在Ruby 2.0中使用ffi gem加載自定義C++函數。當在IRB會議裝載我的自定義庫我的attach_function通話過程中有一個錯誤:爲什麼Ruby FFI不附加自定義共享對象庫中的函數
FFI::NotFoundError: Function 'add' not found in [/usr/local/lib/libbridge.so]
這裏是我創建並檢查了我的libbridge共享對象的方式:
我得到了我的庫中的頭文件:
文件:bridge.h
std::string fooBar(std::string bar);
int add(int a, int b);
的庫實現:
文件:bridge.cpp
#include <iostream>
std::string fooBar(std::string bar)
{
return "foo" + bar;
}
int add(int a, int b)
{
return a + b;
}
爲此,我對我的新庫鏈接二進制代碼:
文件:bridger.cpp
#include <iostream>
#include "bridge.h"
int main(int argc, char* argv[])
{
std::string foobar = fooBar("barrrr");
std::cout << foobar << "\n";
std::cout << "Adding 4 and 2: " << add(4,2) << "\n";
}
首先,我編譯我的lib添加到對象代碼:
$ g++ -c -Wall -Werror -fpic bridge.cpp
然後我使它的共享對象:
$ g++ -shared -o libbridge.so bridge.o
我剝調試符號:
$ strip -o libbridge.so libbridge.so
,並將其移動到我的系統:
$ sudo mv libbridge.so /usr/local/lib/
然後我讓可執行文件,並運行ldconfig:
$ sudo chmod 0755 /usr/local/lib/libbridge.so
$ sudo ldconfig
短檢查:
$ ldd /usr/local/lib/libbridge.so
linux-gate.so.1 => (0xb7781000)
libstdc++.so.6 => /usr/lib/i386-linux-gnu/libstdc++.so.6 (0xb7689000)
libm.so.6 => /lib/i386-linux-gnu/i686/cmov/libm.so.6 (0xb7663000)
libgcc_s.so.1 => /lib/i386-linux-gnu/libgcc_s.so.1 (0xb7645000)
libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb74e2000)
/lib/ld-linux.so.2 (0xb7782000)
我從我的工作目錄中刪除的語言環境版本:
$ rm -f bridge.so
$ rm -f bridge.o
我編譯我的二進制:
$ g++ -Wall -o bridger bridger.cpp -lbridge
我成功地執行它,得到的輸出我的預期:
$ ./bridger
foobarrrr
Adding 4 and 2: 6
現在我創建一個紅寶石模塊ffi_test.rb:
require "ffi"
module FfiTest
extend FFI::Library
ffi_lib_flags :now, :global
ffi_lib "/usr/local/lib/libbridge.so"
attach_function :add, [:int, :int], :int
attach_function :fooBar, [:string], :string
end
當我在IRB會議加載代碼現在我總是得到這個錯誤:
$ irb
2.0.0p247 :001 > load "ffi_test.rb"
FFI::NotFoundError: Function 'add' not found in [/usr/local/lib/libbridge.so]
from /home/me/.rvm/gems/[email protected]/gems/ffi-1.9.0/lib/ffi/library.rb:251:in `attach_function'
from ffi_test.rb:8:in `<module:EricInterface>'
from ffi_test.rb:3:in `<top (required)>'
from (irb):1:in `load'
from (irb):1
from /home/me/.rvm/rubies/ruby-2.0.0-p247/bin/irb:16:in `<main>'
我不明白,這裏的問題是什麼。我的庫顯然會導出:add和:fooBar函數,否則我的橋接器二進制文件將無法成功鏈接到此庫。 Ruby ffi反而無法看到並掛載這些函數。
任何人都可以在這裏指出我正確的方向嗎?
問候 菲利克斯
嘿弗雷德裏克,感謝您的提示。我完全從頭文件和源文件中刪除了函數fooBar。將你的行添加到我的頭文件中,重新編譯並重新安裝這個庫。但錯誤仍然是一樣的。 – GeorgieF
當我將bridge.cpp重命名爲bridge.c並使用gcc而不是g ++時,我得到了這個工作。但我真正想要使用的預期目標庫是C++。那我該如何利用它呢? FFI不支持C++嗎? – GeorgieF
你的bridge.cpp包含bridge.h嗎? –