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>("MyTest").
      define_constructor(Constructor<MyTest>()).
      define_method("read", &MyTest::read);
}

Here are my h and cpp files for MyTest

*** HEADER FILE ***
#ifndef __MyTest_h
#define __MyTest_h

#include <string>
#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/<username>/xtoolkit/public/include
--with-xtoolkit-lib=/Users/<username>/xtoolkit/public/libraries

$ ARCHFLAGS="-arch i386" ruby  extconf.rb
--with-xtoolkit-include=/Users/<username>/xtoolkit/public/include
--with-xtoolkit-lib=/Users/<username>/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/<username>/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/<username>/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/<username>/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/<username>/tests/rice_test2/my_test.bundle
  Expected in: dynamic lookup

dyld: Symbol not found: __ZN9TSXISsE9TerminateEv
  Referenced from: /Users/<username>/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/.