2012-04-15 2 views
4

Ruby 용 C++ 확장을 컴파일하려고하는데 컴파일이 오류를 반환하지 않지만 제대로 컴파일되지 않는 것 같습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?Ruby C++ Extension 컴파일

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

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

extconf.rb :

나는 주 CPP 스크립트를 foo.cpp에

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 

그런 다음, 루비 스크립트 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 : 우분투 리눅스 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++ 사람이 아니기 때문에 너무 용어를 잘못 읽지 않았기를 바랍니다.