Ruby C(++)扩展在.so文件中找不到init函数符号

时间:2015-11-12 00:55:15

标签: c ruby ruby-c-extension

所以现在我只是在Ruby中尝试C / C ++扩展,而且在使用rake-compile gem时我遇到了麻烦。现在我要做的就是定义一个模块,它不会加载Init_ *函数,因为它表示符号是未定义的。但是,当我检查.so文件时,它清楚地列在符号表中:

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扩展问题的信息。也许有什么我想念的?我不知道。

1 个答案:

答案 0 :(得分:4)

Ruby无法找到Init_RFSML,因为该函数的名称实际上是_Z10Init_RSFMLv(删除-C选项以禁用名称解码;实际名称也可能因使用过的编译器。)

因此,您必须使用C链接声明Init_*函数,这些函数不会破坏名称。在C ++中,这是通过extern "C"来完成的,这将得到更彻底的解释here