Building an extension in C++

G

Gary

I'm using cygwin to try to build an extension in C++. I've stripped
down the pickaxe book's example (http://www.rubycentral.com/pickaxe/
ext_ruby.html) to the bare minimum. It looks like:

#include "ruby.h

VALUE cTest;

void Init_Test() {
cTest = rb_define_class("Test", rb_cObject);
}

If I name the file Test.c, it works nicely. If I name the file
Test.cpp I get the following error when I try to require the file in
irb.

LoadError: No such file or directory - /usr/lib/ruby/site_ruby/1.8/
i386-cygwin/Test.so
from /usr/lib/ruby/site_ruby/1.8/i386-cygwin/Text.so
from (irb):1

For the whole proceedure I do:

make clean
ruby extconf.rb
make
make install
irb
require "Test"

Any helpful ideas?
 
M

MenTaLguY

I'm using cygwin to try to build an extension in C++. I've stripped
down the pickaxe book's example (http://www.rubycentral.com/pickaxe/
ext_ruby.html) to the bare minimum. It looks like:

#include "ruby.h

VALUE cTest;

void Init_Test() {
cTest = rb_define_class("Test", rb_cObject);
}

Although it is not the source of the problem with the shared object
not being found, you need to declare Init_Test with C linkage
(extern "C"), or else Ruby will not be able to find the entry point.

Besides this, though, safe handling of C++ and Ruby exceptions is
extremely difficult when writing an extension in C++. You should
probably consider writing the Ruby-facing portion of extension in
C, with a C-linkage interface to the C++ portion of the extension,
and be sure to intercept any C++ exceptions before they can cross
into C or Ruby and create havoc. Similarly, C++ code should not
raise Ruby exceptions or call anything which could raise them.

-mental
 
G

Gary

Thank you mental!!! It works. I should have figured it out myself,
but I needed your help.

I'm I bit confused about a C-linkage interface to the C++ portion. Is
this going to be more than wrapping the C++ calls in try catch(...)
In other words having something like

extern "C" VALUE t_init(VALUE self)
{
//declare any Ruby C++ data conversion vars in C
try
{
//call C++ functions
}
catch(...)
{
//process exceptions
}
//Do any data interactions between C++ and Ruby
}

Once again, thanks! I spent several hours stumped.

-Gary
 
R

Robert Klemme

Thank you mental!!! It works. I should have figured it out myself,
but I needed your help.

I'm I bit confused about a C-linkage interface to the C++ portion. Is
this going to be more than wrapping the C++ calls in try catch(...)
In other words having something like

extern "C" VALUE t_init(VALUE self)
{
//declare any Ruby C++ data conversion vars in C
try
{
//call C++ functions
}
catch(...)
{
//process exceptions
}
//Do any data interactions between C++ and Ruby
}

Once again, thanks! I spent several hours stumped.

That'll probably suffice. You might get a bit better results by
catching explicit exception types and converting them to Ruby world
exceptions. Other than that your code should prevent any havoc caused
by C++ exceptions raised into the Ruby interpreter.

Kind regards

robert
 
G

Gary

Thank you Robert! I agree and understand about catching and
converting C++ exceptions to Ruby exceptions.

Now, on to my next problem. When I try using new I get linker errors
(grrr)

extern "C" void Init_Test() {
cTest = rb_define_class("Test", rb_cObject);

try
{
int *x=new int;
}
catch (...)
{
}
}

I get the following errors:

undefined reference to '___gxx_personality_sj0'
undefined reference to 'operator new(unsigned int)
undefined reference to '___cxa_begine_catch'
undefined reference to '___cxa_end_catch'

It compiles nicely if I replace:
int *x=new int;
with
int *x=NULL

-Gary
 
G

Gary

Are you compiling with gcc or g++?

Paul

When I type make the line says

g++ (blah blah blah)

Although when I look at the Makefile it has the following line:

CC = gcc

If it is any help, my extconf.rb is as follows:

require 'mkmf'
create_makefile("Test")

I hope I've given you as much information as you need, and perhaps
more =-)

Thank you Paul
 
N

Nobuyoshi Nakada

Hi,

At Sat, 27 Oct 2007 06:25:00 +0900,
Gary wrote in [ruby-talk:276038]:
Although when I look at the Makefile it has the following line:

CC = gcc

mkmf.rb in 1.8 doesn't support C++.

Perhaps make has default macro CXX and a rule for C++. But C++ runtime
library isn't linked by default using gcc, you'll need to add the
library in extconf.rb explicitly, like as:

have_library("stdc++")
 
G

Gary

Thank you Nobu!!! Your a genius!

This cleared up the last of my problems! Wheee!!!!

-Gar

Hi,

At Sat, 27 Oct 2007 06:25:00 +0900,
Gary wrote in [ruby-talk:276038]:
Although when I look at the Makefile it has the following line:

mkmf.rb in 1.8 doesn't support C++.

Perhaps make has default macro CXX and a rule for C++. But C++ runtime
library isn't linked by default using gcc, you'll need to add the
library in extconf.rb explicitly, like as:

have_library("stdc++")
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top