2012-04-15 156 views
4

我試圖編譯一個Ruby的C++的擴展,並編制不返回一個錯誤,但它似乎並沒有被正確編譯。我究竟做錯了什麼?編譯Ruby的C++擴展

我有主CPP腳本Foo.cpp中

#include <iostream> 
#include <ruby.h> 
extern "C" 

VALUE cFoo; 
void Init_foo(){cFoo = rb_define_class("Foo", rb_cObject);} 

extconf.rb

require "mkmf" 
$libs += " -lstdc++ " 
create_makefile("foo") 

和這些文件的目錄中,我做了

$ ruby extconf.rb 
creating Makefile 
$ make 
compiling foo.cpp 
linking shared-object foo.so 
$ ls 
Makefile extconf.rb foo.cpp foo.o foo.so 

然後,我公頃已經Ruby腳本test.rb

#!/usr/bin/env ruby 
require "path_to_this_directory/foo" 

,我跑test.rb。它返回一個錯誤:

... in `require': .../foo.so: undefined symbol: cFoo - .../foo.so (LoadError) 

我在做什麼錯?

環境

  • 操作系統:Ubuntu Linux操作系統的11.10
  • 紅寶石:1.9.3

回答

1

你宣稱cFoo存在:

extern "C" 

VALUE cFoo; 

但你永遠不定義它。話說extern "C" blahblah只是說,blahblah存在,它是外部可見的,並且它不會有它的名字錯位(即「C」鍵),但一個extern聲明實際上並不定義任何東西; extern說的東西存在,但它並沒有把它納入存在。

你的C++應該看起來更像是這樣的:

#include <iostream> 
#include <ruby.h> 

extern "C" VALUE cFoo; 
extern "C" void Init_foo(); 

VALUE cFoo; 
void Init_foo(){cFoo = rb_define_class("Foo", rb_cObject);} 

需要兩個extern "C"告訴C++編譯器單獨再留下名字單獨定義的符號。你也可以這樣說:

#include <iostream> 
#include <ruby.h> 

extern "C" VALUE cFoo; 

VALUE cFoo; 
extern "C" void Init_foo(){cFoo = rb_define_class("Foo", rb_cObject);} 

我不確定第二個版本是標準C++還是GCC擴展。

我沒有太大的C++的人,所以我希望我沒有屠殺的術語太嚴重的。