Hi all,

I have a problem that is hopefully easy to solve for you guys: I have written a rather large C++ program as part of my Master's. Now, I have to use an open source C-library (http://www.tbi.univie.ac.at/~ivo/RNA/RNAlib_toc.html). I have never tried to combine C and C++. To figure out how to do this, I tried to take the small example C-program from the homepage (http://www.tbi.univie.ac.at/~ivo/RNA/RNAlib.html#SEC16) and treat it as a C++ program. I added
#include <malloc.h>
#include <string.h>
and saved the program as TestVienna.cc. I have also downloaded the Vienna-package and installed it as described on the homepage. Now, I tried to compile TestVienna.cc as follows:
optiplex9:~/SSPMARS> g++ TestVienna.cc -o TestVienna -I ../bin/ViennaRNA-1.4/H/ -L ../bin/ViennaRNA-1.4/lib/ -lRNA -lm

That gives the following list of errors:
TestVienna.o(.text+0x39): In function `main':
: undefined reference to `initialize_fold(int)'
TestVienna.o(.text+0x4d): In function `main':
: undefined reference to `space(unsigned)'
TestVienna.o(.text+0x62): In function `main':
: undefined reference to `fold(char*, char*)'
TestVienna.o(.text+0x79): In function `main':
: undefined reference to `space(unsigned)'
TestVienna.o(.text+0x8e): In function `main':
: undefined reference to `fold(char*, char*)'
TestVienna.o(.text+0x96): In function `main':
: undefined reference to `free_arrays()'
TestVienna.o(.text+0xa1): In function `main':
: undefined reference to `expand_Full(char const*)'
TestVienna.o(.text+0xaf): In function `main':
: undefined reference to `make_tree(char*)'
TestVienna.o(.text+0xbd): In function `main':
: undefined reference to `Make_swString(char*)'
TestVienna.o(.text+0xd6): In function `main':
: undefined reference to `expand_Full(char const*)'
TestVienna.o(.text+0xe4): In function `main':
: undefined reference to `make_tree(char*)'
TestVienna.o(.text+0xf2): In function `main':
: undefined reference to `Make_swString(char*)'
TestVienna.o(.text+0x11c): In function `main':
: undefined reference to `tree_edit_distance(Tree*, Tree*)'
TestVienna.o(.text+0x12a): In function `main':
: undefined reference to `free_tree(Tree*)'
TestVienna.o(.text+0x135): In function `main':
: undefined reference to `free_tree(Tree*)'
TestVienna.o(.text+0x141): In function `main':
: undefined reference to `unexpand_aligned_F(char**)'
TestVienna.o(.text+0x178): In function `main':
: undefined reference to `string_edit_distance(swString*, swString*)'
TestVienna.o(.text+0x233): In function `main':
: undefined reference to `init_pf_fold(int)'
TestVienna.o(.text+0x245): In function `main':
: undefined reference to `pf_fold(char*, char*)'
TestVienna.o(.text+0x25b): In function `main':
: undefined reference to `Make_bp_profile(int)'
TestVienna.o(.text+0x270): In function `main':
: undefined reference to `pf_fold(char*, char*)'
TestVienna.o(.text+0x286): In function `main':
: undefined reference to `Make_bp_profile(int)'
TestVienna.o(.text+0x28e): In function `main':
: undefined reference to `free_pf_arrays()'
TestVienna.o(.text+0x2a0): In function `main':
: undefined reference to `profile_edit_distance(float**, float**)'
TestVienna.o(.text+0x2e1): In function `main':
: undefined reference to `free_profile(float**)'
TestVienna.o(.text+0x2ec): In function `main':
: undefined reference to `free_profile(float**)'
collect2: ld returned 1 exit status

What am I doing wrong? If I try the same with the C-version of the program (TestVienna.c) it works without any problems:
optiplex9:~/SSPMARS> gcc TestVienna.c -o TestVienna -I ../bin/ViennaRNA-1.4/H/ -L ../bin/ViennaRNA-1.4/lib/ -lRNA -lm
optiplex9:~/SSPMARS> ./TestVienna
(((.(((...)))_)))
(((_(((...))).))) 2.00
(R(P(P(P(UU)(P(P(P(UU)(UU)(UU)P)P)P)____P)P)P)R) mfe=-6.57
(R(P(P(P____(P(P(P(UU)(UU)(UU)P)P)P)(UU)P)P)P)R) mfe=-7.64 dist=2.00
(((._(_(,._..))__)))) free energy=-7.32
(((((_(__.._.))).)_)) free energy=-7.92 dist=2.95

I really hope you can help since I can't figure it out. I have tried to google the problem but without any luck.

-Stinus Lindgreen, Denmark

you didn't do anything "wrong". There are a lot of porting issues you must deal with when porting C programs to C++. Most (if not all) the errors you are getting are probably because the functions have not been prototyped before used in main(). You need the *.h file that prototypes all the functions in that library.

If the program is already including the correct header files, make sure the prototypes contain the correct parameter list -- c++ is picky about that. For example, c++ initialize_fold(int) is not the same as initialize_fold()

Second issue: when you get everything to compile correct, it may not link with that C library. C++ normally "mangles" function names, while C does not. To keep c++ from doing that so that the program can be linked with C libraries you have to declare the functions as Extern "C". Here is an example -- you will find many other examples in your c++ compiler's standard include directory.

#ifdef _cplusplus // if compiled with C++ compiler.  Note that this is not
// standard, check your compiler's docs and other header files to find out
// the correct macro it uses for c++ versus C compilations.
extern "C" {
#endif
//
// put C function prototypes here
int intialize_fold(int);
// other function prototypes here


#ifdef _cplusplus // if compiled with C++ compiler
} // end of extern "C" block
#endif

Thanks a lot. It now compiles and runs correctly. Next step is to use their functions in my program - but that is not your problem :) Now I can finally move on to the interesting things instead of dealing with compiler errors.

-Stinus

This question has already been answered. Start a new discussion instead.