Forum Stats

  • 3,851,951 Users
  • 2,264,054 Discussions
  • 7,904,915 Comments

Discussions

Unable to resolve iostream symbols in shared library

807575
807575 Member Posts: 16,875
I am trying to create a (shared) library, which exports a C++ function to C using the 'extern "C"' syntax. To be able to link this library to a normal C programm all C++ specific symbols have to be resolved IN the library. That is, they can not be resolved at link time because a C programm typically does not have any knowledge on how to resolve C++ symbols.
I am using the following compiler command to perfor this task:

CC -G -lCrun -lCstd

This works for the most complicated C++ code...Except for code, that contains iostream commands, e.g. 'cerr << "Hello";'
I am unable to resolve the iostream symbols in the library and therfore I get linker errors, when linking to C code. The project I am working on is somewhat complex and unfortunately requires this structure. I have written a very short example to document the behavior:

function.cpp (the C++ code):
#include <iostream>
#include <vector>

extern "C" {
void function(int i) {
std::vector<int> v(1);
v[1]=1;
// the following statement will add iostream symbols to the object.
// these symbols can not be resolved. Comment out the line and it works
std::cerr << v[1];
}
}

cmain.c (the C code):
void function(int);

main() {

function(42);
}

Makefile (watch the tabs):
cmain: cmain.o function.so
cc -o cmain cmain.o function.so
function.so: function.o
CC -G -lCrun -lCstd -o function.so function.o
function.o: function.cpp
CC -c function.cpp
cmain.o: cmain.c
cc -c cmain.c

Comments

  • 807575
    807575 Member Posts: 16,875
    Sorry for the messed up formatting (where is that edit button?):

    function.cpp (the C++ code):
    <pre>
    #include <iostream>
    #include <vector>

    extern "C" {

    void function(int i) {
    // use a vector just to prove we are doing 'real' C++
    std::vector<int> v(1);
    v[1]=1;
    // the following statement will add iostream symbols to the object
    // these symbols can not be resolved. Comment out the line to make
    // the project work.
    std::cerr << v[1];
    }
    }
    </pre>

    cmain.c (the C code):
    <pre>
    void function(int);

    main() {

    function(42);
    }
    </pre>

    Makefile (watch the tabs):
    <pre>
    cmain: cmain.o function.so
    cc -o cmain cmain.o function.so
    function.so: function.o
    CC -G -lCrun -lCstd -o function.so function.o
    function.o: function.cpp
    CC -c function.cpp
    cmain.o: cmain.c
    cc -c cmain.c

    </pre>
  • 807575
    807575 Member Posts: 16,875
    I tried your code and could see the error messages:

    #cc -o cmain cmain.o -lfunction
    Undefined first referenced
    symbol in file
    __1cDstdEcerr_ ./libfunction.so
    __1cDstdNbasic_ostream4Ccn0ALchar_traits4Cc___2l6Mi_r1_ ./libfunction.so
    ld: fatal: Symbol referencing errors. No output written to cmain

    I also tried linking with -lCstd -lCrun and it compiled fine:

    #cc -o cmain cmain.o -lfunction -lCstd -lCrun
    #./cmain
    #

    Btw, there is an option -xflag={CC,CC4,f77,f90} being considered.
    With this flag, if the user is compiling with the cc driver and linking in C++ object files/libraries, the command line would be:

    cc *.c *.o -xlang=CC
    ^
    |
    C++ objects

    This option might be avilable in the future.

    Hope this helps!

    Thanks,
    -Prasad
  • 807575
    807575 Member Posts: 16,875
    In the above posting the usage is

    cc *.c *.o -xlang=CC where *.o are C++ objects

    Thanks,
    -Prasad
  • 807575
    807575 Member Posts: 16,875
    You are rigth it works!

    My mistake was in the wrong sequence of libraries, i.e. Cstd and Crun have to come last. With my small example everything is fine now. I will try to adopt it to my real project.

    Thank you!

    Jan
This discussion has been closed.