I'll try to explain:
I have two Files:
- The first one is a cpp file that wraps the functionality I want into
a function. I compile this one with g++ to an object file
- The second file is a .c file (my ruby extension). I compile this
with gcc because g++ gives errors like:
bash-2.05b$ g++ -c cRubyTest.c
cRubyTest.c: In function `void Init_cRubyTest()':
cRubyTest.c:56: error: invalid conversion from `VALUE (*)(long
unsigned int)'
to `VALUE (*)(...)'
C++ is much stricter when it comes to what kindes of type-casts are
allowed - especially when you use the "old-style" "(<type>)value" casts
(e.g "(char*)void_ptr"). You might have to use new-style C++-only casting
using
static_cast, reinterpret_cast,...
I got the code from the pickaxe book and don't know with this doesn't
work with g++. gcc compiles correctly to an object file.
See above.
- But if I try to link (with g++ cRubyTest.o cr.o -lcryptopp) ld sais:
cRubyTest.o(.text+0x1b): In function `cfunc':
: undefined reference to `GenerateRSAKey'
collect2: ld returned 1 exit status
where GenerateRSAKey is the wrapper function from the cpp file.....
When compiling plain C code, the symbols in the generated .o file are
named like the function they are describing.
With C++, however, it works differently, because you can have more than
one function with the same name (but different count or types or
arguments) in C++. The compiler therefore encodes the signature (the
order, count, and type of the arguments) of a function into its name -
e.g.
the symbol for "int my_func(char*, int)" might be
"int__my_func__char_star__int" (the actual name-mangling the gcc uses is
different, and less human-readable, but you get the idea). Since you
compiled one file with gcc, and the other with g++, the same function
"GenerateRSAKey" is mapped to different symbol names - which of course
makes the linker complain that it can't find the referenced symbols.
I believe you have to wrap the function-declaration of GenerateRSAKey"
(inside your cpp-source) in an 'export "C"' clause. This tells the
compiler that it should generate symbols compatible with C, algtough the
file contains C++ code.
So, instead of declaring GenerateRSAKey with
return_type GenerateRSAKey(type_1 arg1, type_2 arg2, ...) ;
you declare it writing
export "C" {
return_type GenerateRSAKey(type_1 arg1, type_2 arg2, ...) ;
}
I hope I got the syntax of the "export" clause right - I haven't activly
programmed C++ for a few years, and I'm too lazy to look it up right now
;-))
greetings, Florian Pflug