2015-11-12 65 views
1

所以現在我只是嘗試了Ruby中的C/C++擴展,並且在使用rake-compile gem時遇到了麻煩。現在我所要做的就是定義一個模塊,它不會加載Init_ *函數,因爲它說符號是未定義的。但是,當我檢查.so文件它在符號表中清楚列明:Ruby C(++)在.so文件中找不到init函數符號的擴展

nm -gC RSFML.so         

0000000000201038 B __bss_start 
       w __cxa_finalize 
0000000000201038 D _edata 
0000000000201050 B _end 
0000000000000744 T _fini 
       w __gmon_start__ 
00000000000005e0 T _init 
       w _ITM_deregisterTMCloneTable 
       w _ITM_registerTMCloneTable 
       w _Jv_RegisterClasses 
       U rb_define_module 
0000000000201040 B RSFML 
0000000000201048 B RSFML_Window 
0000000000000725 T Init_RSFML() 

下面是我從IRB得到錯誤:

irb -r ./lib/RSFML      
/home/z/.rvm/rubies/ruby-2.2.1/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require':LoadError: /home/z/Programming/ruby/RSFML-Gem/lib/RSFML.so: undefined symbol: Init_RSFML - /home/z/Programming/ruby/RSFML-Gem/lib/RSFML.so 

我極其混亂,有沒有似乎在C擴展的問題上有很多信息。也許有一些我錯過了?我不知道。

+0

**舊評論刪除**這工作,我覺得自己像一個白癡。謝謝! – SeedyROM

+0

至少現在它加載,試圖定義一個模塊,singleton_method甚至不會讓我現在編譯。 (呃...) – SeedyROM

回答

4

紅寶石找不到,因爲該函數的名稱Init_RFSML實際上是_Z10Init_RSFMLv(降-C選項來禁用名稱demangling;實際名稱可能還取決於所使用的編譯器有所不同)。

所以你必須聲明Init_*函數與C不鏈接名稱的聯繫。在C++中,這是通過extern "C"完成的,其更詳細的解釋如下:here

+0

所以,現在我已經對此進行了整理,我怎樣才能調用C++函數並從C++庫聲明對象?因爲當我包含文件時,所有的符號都會被破壞,函數期望它們是外部的「C」d。或者是不可能的,我應該放棄過夜(哈哈) – SeedyROM

+1

@Rust:這是一個新問題,還是您需要關於這個問題的其他信息?通常你只需要在入口點('Init_ *')使用'extern「C''。如果它是新的,你可能會考慮問一個新的問題(包括任何錯誤信息和可能相關的源代碼)。 – cremno