From: Lea Savage Date: 2010-04-17T01:05:58+09:00 Subject: Extending Ruby using C++ and Rice Hi, I am trying to extend Ruby and my current implementation is using C++ and Rice (http://rice.rubyforge.org/main.html). Mac OS X 10.5.8 Ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0] I have completed the following steps as shown in Rice to create a cpp class (my_test.cpp) #include "rice/Class.hpp" #include "rice/Data_Type.hpp" #include "rice/Constructor.hpp" #include "MyTest.h" using namespace Rice; extern "C" void Init_my_test() { define_class("MyTest"). define_constructor(Constructor()). define_method("read", &MyTest::read); } Here are my h and cpp files for MyTest *** HEADER FILE *** #ifndef __MyTest_h #define __MyTest_h #include #include "XternalDebug.hpp" class MyTest { public: MyTest() {}; virtual ~MyTest(void){ SX::Terminate(); SXMP::Terminate(); } std::string read(std::string filename); }; #endif *** CPP FILE *** #include "MyTest.h" extern "C" std::string MyTest::read(std::string filename) { if(SXMP::Initialize()) { // Must initialize SX before we use it if (SX::Initialize()) { std::string status = ""; bool ok; SX myFile; myFile.OpenFile(filename, UnknownFile, opts); std::string buffer; myFile.Get(&buffer); return buffer; } } return NULL; } SX and SXMP are taken from another library called libXternalDebug.a My extconf.rb file looks as follows: require 'rubygems' require 'mkmf-rice' $CPPFLAGS << ' -DMAC_ENV=1' have_library("stdc++") dir_config("xtoolkit") have_library("XternalDebug") create_makefile("my_test") I pass the following arguments to extconf.rb ARCHFLAGS="-arch i386" ruby extconf.rb --with-xtoolkit-include=/Users//xtoolkit/public/include --with-xtoolkit-lib=/Users//xtoolkit/public/libraries $ ARCHFLAGS="-arch i386" ruby extconf.rb --with-xtoolkit-include=/Users//xtoolkit/public/include --with-xtoolkit-lib=/Users//xtoolkit/public/libraries checking for main() in -lrice... yes checking for main() in -lstdc++... yes checking for main() in -lX... yes creating Makefile I then run make: $ makeg++ -I. -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0 -I. -I/Users//xtoolkit/public/include -I/Library/Ruby/Gems/1.8/gems/rice-1.3.1/ruby/lib/include -DMAC_ENV=1 -fno-common -arch i386 -Os -pipe -fno-common -Wall -g -c my_test.cpp g++ -I. -I. -I/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/1.8/universal-darwin9.0 -I. -I/Users//xtoolkit/public/include -I/Library/Ruby/Gems/1.8/gems/rice-1.3.1/ruby/lib/include -DMAC_ENV=1 -fno-common -arch i386 -Os -pipe -fno-common -Wall -g -c MyTest.cpp g++ -arch i386 -pipe -bundle -undefined dynamic_lookup -o my_test.bundle my_test.o MyTest.o -L. -L/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib -L/Users//xtoolkit/public/libraries -L. -arch i386 -L/Library/Ruby/Gems/1.8/gems/rice-1.3.1/ruby/lib/lib -lXternalDebug -lstdc++ -lrice -lruby -lpthread -ldl -lm (please note i have removed my username intentionally from the above paths) I then have the following ruby test: require 'my_test' require 'test/unit' class TestTest < Test::Unit::TestCase def test_test t = MyTest.new assert_equal(Object, MyTest.superclass) assert_equal(MyTest, t.class) end end When I try to run this I get the following error: $ ruby testtest.rb Loaded suite testtest Started . Finished in 0.000476 seconds. 1 tests, 2 assertions, 0 failures, 0 errors dyld: lazy symbol binding failed: Symbol not found: __ZN9TSXMISsE9TerminateEv Referenced from: /Users//tests/rice_test2/my_test.bundle Expected in: dynamic lookup dyld: Symbol not found: __ZN9TSXISsE9TerminateEv Referenced from: /Users//tests/rice_test2/my_test.bundle Expected in: dynamic lookup Trace/BPT trap The above does show the 2 tests as passing but then I get the error below when it is deconstructing the class at it uses the external library. Does anyone know what I am doing wrong or what I am missing to get these errors? Do I need to include this external library in a particular directory for ruby to discover? Any help is much appreciated. I have also heard of using a combination of FFI and SWIG but how does this work when it is an external library and I do not have the source? Lea -- Posted via http://www.ruby-forum.com/.