Ruby/DL and C++ libraries

I’m trying to use a C++ shared library from Ruby and wanted to use
Ruby/DL to do it. It seemed straightforward enough, but I can’t seem
to match the signature on the function I want to import.

Here’s a simplified example:

···

bash $ cat dlexample.cpp
#include
#include

extern “C” void place( const std::string &text)
{
std::cout << text << std::endl ;
}
bash $ cat dlexample.rb
require 'dl/import’
module Test
extend DL::Importable
dlload ‘dlexample.so

    typealias 'string', 'p'
    extern "void place(string)"

end

Test.place(“text”)

bash $ g++ -shared -fPIC -o dlexample.so dlexample.cpp
bash $ LD_LIBRARY_PATH="." ruby dlexample.rb
(eval):5: [BUG] Segmentation fault
ruby 1.8.1 (2004-02-06) [x86_64-linux-gnu]

Aborted

It works with C functions (change the “const std::string &” to a
"const char *" and it’s all good).

I have a feeling this can work with the write typealias and encoding
functions, but I’m fairly new to Ruby and would appreciate any
pointers.

I have a workaround in place using Swig, but if I go that route, I may
as well just code up the utility in C++.

Thanks in advance,
Bheeshmar Redheendran

extern “C” void place( const std::string &text)
{
std::cout << text << std::endl ;
}
:
It works with C functions (change the “const std::string &” to a
“const char *” and it’s all good).

I have a feeling this can work with the write typealias and encoding
functions, but I’m fairly new to Ruby and would appreciate any
pointers.

A const std::string & is not a const char *.
C (dl.so) doesn’t know how to construct/destruct std::string.

Use C-compatible types only, or write an extension library using
Ruby APIs. SWIG is one of nice solution I think.

To write a generic C++/Ruby interface is as hard as to write a
C++ compiler.

–[ Tietew ]-------------------------------------------------------
Mail: tietew@tietew.net / tietew@raug.net
Web : http://www.tietew.net/ (Tietew Windows Lab.)
PGP fingerprint: 26CB 71BB B595 09C4 0153 81C4 773C 963A D51B 8CAA

···

On Fri, 26 Mar 2004 12:04:28 +0900 In article f83335be.0403251902.40fd22c9@posting.google.com [Ruby/DL and C++ libraries] google@redheendran.com (Bheeshmar Redheendran) wrote:

You will run into a number of problems using Ruby/DL with C++ code:

  • C++ function names are mangled, but there is no standard for how
    this mangling is done. You will need to mangle your function name
    in the same way as the C++ implementation on your platform does.

  • C++ exceptions are not compatible with Ruby exceptions. If your C++
    code throws an exception, then your program will have undefined
    behavior (it will likely call abort()).

  • C++ objects have constructors and destructors, and Ruby/DL doesn’t
    know how to deal with these. So if your C++ code returns an object
    by value, you might be able to get Ruby to wrap it, but getting Ruby
    to destruct the object when it is no longer used is a different
    story.

  • C++ has references in addition to pointers. Ruby/DL doesn’t know
    how to deal with references, though I suspect they should work
    similar to pointers.

You are probably better off using swig instead.

Paul

···

On Fri, Mar 26, 2004 at 12:04:28PM +0900, Bheeshmar Redheendran wrote:

I’m trying to use a C++ shared library from Ruby and wanted to use
Ruby/DL to do it. It seemed straightforward enough, but I can’t seem
to match the signature on the function I want to import.

In article 20040326130655.CC26.TIETEW-ML-RUBY-TALK@tietew.net,

···

Tietew tietew-ml-ruby-talk@tietew.net wrote:

On Fri, 26 Mar 2004 12:04:28 +0900 >In article f83335be.0403251902.40fd22c9@posting.google.com >[Ruby/DL and C++ libraries] >google@redheendran.com (Bheeshmar Redheendran) wrote:

extern “C” void place( const std::string &text)
{
std::cout << text << std::endl ;
}
:
It works with C functions (change the “const std::string &” to a
“const char *” and it’s all good).

I have a feeling this can work with the write typealias and encoding
functions, but I’m fairly new to Ruby and would appreciate any
pointers.

A const std::string & is not a const char *.
C (dl.so) doesn’t know how to construct/destruct std::string.

Use C-compatible types only, or write an extension library using
Ruby APIs. SWIG is one of nice solution I think.

Swig is great when you’ve got the source code for the library available.
If you’ve got a shared library and an API reference for it (but no source
code) then Ruby/DL seems like the way to go.

Are you saying that Ruby/DL won’t work with a shared library that was
developed in C++?

Phil