2012-04-15 85 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++的人,所以我希望我没有屠杀的术语太严重的。