所以现在我只是在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扩展问题的信息。也许有什么我想念的?我不知道。
答案 0 :(得分:4)
Ruby无法找到Init_RFSML
,因为该函数的名称实际上是_Z10Init_RSFMLv
(删除-C
选项以禁用名称解码;实际名称也可能因使用过的编译器。)
因此,您必须使用C链接声明Init_*
函数,这些函数不会破坏名称。在C ++中,这是通过extern "C"
来完成的,这将得到更彻底的解释here。