[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Building an extension in C++

Gary

10/19/2007 10:15:00 PM


I'm using cygwin to try to build an extension in C++. I've stripped
down the pickaxe book's example (http://www.rubycentral.co...
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?

8 Answers

MenTaLguY

10/19/2007 10:33:00 PM

0

On Sat, 20 Oct 2007 07:15:05 +0900, Gary <gapjunk@gmail.com> wrote:
> I'm using cygwin to try to build an extension in C++. I've stripped
> down the pickaxe book's example (http://www.rubycentral.co...
> 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


Gary

10/20/2007 3:20:00 PM

0


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

On Oct 19, 3:33 pm, MenTaLguY <men...@rydia.net> wrote:
> On Sat, 20 Oct 2007 07:15:05 +0900, Gary <gapj...@gmail.com> wrote:
> > I'm using cygwin to try to build an extension in C++. I've stripped
> > down the pickaxe book's example (http://www.rubycentral.co...
> > 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


Robert Klemme

10/20/2007 4:05:00 PM

0

On 20.10.2007 17:19, Gary wrote:
> 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

Gary

10/20/2007 4:53:00 PM

0


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

On Oct 20, 9:05 am, Robert Klemme <shortcut...@googlemail.com> wrote:
> On 20.10.2007 17:19, Gary wrote:
>
>
>
>
>
>
>
> > 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


Paul Brannan

10/24/2007 1:56:00 PM

0

On Sun, Oct 21, 2007 at 01:55:03AM +0900, Gary wrote:
> Now, on to my next problem. When I try using new I get linker errors
> (grrr)

Are you compiling with gcc or g++?

Paul


Gary

10/26/2007 9:23:00 PM

0

On Oct 24, 6:55 am, Paul Brannan <pbran...@atdesk.com> wrote:
> On Sun, Oct 21, 2007 at 01:55:03AM +0900, Gary wrote:
> > Now, on to my next problem. When I try using new I get linker errors
> > (grrr)
>
> 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



Nobuyoshi Nakada

10/26/2007 11:40:00 PM

0

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++")

--
Nobu Nakada

Gary

10/28/2007 12:49:00 PM

0



Thank you Nobu!!! Your a genius!

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

-Gar

On Oct 26, 4:40 pm, Nobuyoshi Nakada <n...@ruby-lang.org> wrote:
> 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++")
>
> --
> Nobu Nakada