FFI with a C++ Library

This may be more of a C++ question but here goes:

I’m trying to use Ruby FFI with a CPP library but when I compile my CPP
library and look at the method names there’s always a __Z5, __Z4, or
__Z3 in
front of the method name. I see this when I run nm against the dynlib
file.

Oddly when I compile a C file it works fine but I can use a C file
because
I’m using some CPP libraries in my library.

Anyone have any ideas on how to make my library use normal names?

This is what my test file looks like:

foo.cpp

void foo{}

To build the library I do this:

g++ -c foo.cpp
g++ -dynamiclib foo.o -o foo.dylib

To look at the method name I do this:
nm -fgj foo.dylib

And this is what I get:
__Z3foov
___gxx_personality_v0
dyld_stub_binder

Any help is greatly appreciated.

Mike

On Jul 9, 2011, at 12:40 AM, Mike B. wrote:

This may be more of a C++ question but here goes:

I’m trying to use Ruby FFI with a CPP library but when I compile my CPP
library and look at the method names there’s always a __Z5, __Z4, or __Z3 in
front of the method name. I see this when I run nm against the dynlib file.

Oddly when I compile a C file it works fine but I can use a C file because
I’m using some CPP libraries in my library.

This is due to what’s called “name mangling” - it’s how C++
differentiates different functions with the same name based on
namespace, overloads, etc. You can learn more on
Wikipedia [0].

To resolve this, you need to specify the functions being
called with C linkage. Wrap the necessary function as
follows in your .cpp/.cc file:

extern “C” {
void foo(…) {
}
}

This will give foo the external name “foo” instead of how
it would be defined with C++ linkage.

If you have C headers and see them being used from
C++ and wish to keep the unmangled names, you can
add this to the top of your C header:

#ifdef __cplusplus
extern “C” {
#endif

and this at the bottom:

#ifdef __cplusplus
}
#endif

[0] Name mangling - Wikipedia

Michael E.
[email protected]
http://carboni.ca/

On Jul 9, 2011, at 1:16 AM, Michael E. wrote:

This is due to what’s called “name mangling” - it’s how C++
}
extern “C” {

Michael E.
[email protected]
http://carboni.ca/

Another solution is to use the Rice library (http://rice.rubyforge.org/)
to build C++ bindings. That said, depending on the size of the C++ code
you’re working with, it’s probably simpler to go with your own code
inside an extern C { } as Michael explained above and from that you can
use FFI.

Jason