2012-04-15 5 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) 

私は間違っていますか?

環境

  • OS: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);} 

は、次の2つの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);} 

2番目のバージョンが標準のC++またはGCC拡張であるかどうかはわかりません。

私はあまりC++の人ではないので、私は用語をあまりにもひどく虐待していないことを願っています。

関連する問題