extern "C"

Discussion in 'C++' started by Karel Van Laer, Sep 4, 2008.

  1. Hi everyone,

    I need to be able to mix C and C++.
    The main program is written in C and needs to access C++ code.
    To be more specific it's a user defined function in fluent, but this
    should not be relevant.

    I've allready read that i need to use the extern "C" construction but i
    don't seem to be doing it right.

    So far i've got this compiled:

    <file: cpplib.cpp>
    extern "C" int function(); //declaration
    int function(){...} //definition
    </file: cpplib.cpp>

    <file: cpplib.h>
    int function(){}
    </file: cpplib.h>

    <file: cprogram>
    #include "cpplib.h"
    ...//call "function()" somewhere
    </file: cprogram>

    When i try to run it this generates the following error:
    /opt/Fluent.Inc/fluent6.3.26/lnx86/2d/fluent.6.3.26: symbol lookup
    error: libudf/lnx86/2d/libudf.so: undefined symbol: init
    "init" is the function i'm trying to call here.

    I'm hoping somebody here can give me an idea of what i'm doing wrong here.

    Karel
     
    Karel Van Laer, Sep 4, 2008
    #1
    1. Advertising

  2. You are right about the readability of my code.
    So i'll respond with a cleaner version

    <file: cpplib.h>
    #ifdef __cplusplus
    extern "C" {
    #endif
    int init(); //declaration
    #ifdef __cplusplus
    }
    #endif
    </file: cpplib.h>

    <file: cpplib.cpp>
    #include "cpplib.h"
    int init(){...} //definition
    </file: cpplib.cpp>

    <file: cprogram>
    #include "cpplib.h"
    ...//call "init()" somewhere
    </file: cprogram>

    the result remains the same:
    /opt/Fluent.Inc/fluent6.3.26/lnx86/2d/fluent.6.3.26: symbol lookup
    error: libudf/lnx86/2d/libudf.so: undefined symbol: init

    Karel

    Victor Bazarov wrote:
    > Karel Van Laer wrote:
    >> I need to be able to mix C and C++.
    >> The main program is written in C and needs to access C++ code.
    >> To be more specific it's a user defined function in fluent, but this
    >> should not be relevant.
    >>
    >> I've allready read that i need to use the extern "C" construction but i
    >> don't seem to be doing it right.
    >>
    >> So far i've got this compiled:
    >>
    >> <file: cpplib.cpp>
    >> extern "C" int function(); //declaration

    > ^^^^^^^^^^^^^^^^^^^^^^^^^
    > Drop that. Instead do
    >
    > #include "cpplib.h"
    >
    >> int function(){...} //definition
    >> </file: cpplib.cpp>
    >>
    >> <file: cpplib.h>
    >> int function(){}

    >
    > That's simply wrong. You shouldn't *define* functions in headers like
    > that. Think about it: the empty body? What you should have do is:
    >
    > #ifdef __cplusplus
    > extern "C"
    > #endif
    > int function();
    >
    >> </file: cpplib.h>
    >>
    >> <file: cprogram>
    >> #include "cpplib.h"
    >> ...//call "function()" somewhere
    >> </file: cprogram>
    >>
    >> When i try to run it this generates the following error:
    >> /opt/Fluent.Inc/fluent6.3.26/lnx86/2d/fluent.6.3.26: symbol lookup
    >> error: libudf/lnx86/2d/libudf.so: undefined symbol: init
    >> "init" is the function i'm trying to call here.

    >
    > 'init'? How does the 'init' play into all that? Isn't your function
    > called 'function'?
    >
    >>
    >> I'm hoping somebody here can give me an idea of what i'm doing wrong
    >> here.

    >
    > For one, you're not posting your real code.
    >
    > V
     
    Karel Van Laer, Sep 4, 2008
    #2
    1. Advertising

  3. Karel Van Laer

    Uwe Schmitt Guest

    On 4 Sep., 16:53, Karel Van Laer <> wrote:
    > You are right about the readability of my code.
    > So i'll respond with a cleaner version
    >
    > <file: cpplib.h>
    >       #ifdef __cplusplus
    >       extern "C" {
    >       #endif
    >       int init(); //declaration
    >       #ifdef __cplusplus
    >       }
    >       #endif
    > </file: cpplib.h>
    >
    > <file: cpplib.cpp>
    >      #include "cpplib.h"
    >      int init(){...} //definition
    > </file: cpplib.cpp>
    >
    > <file: cprogram>
    >      #include "cpplib.h"
    >      ...//call "init()" somewhere
    > </file: cprogram>
    >
    > the result remains the same:
    > /opt/Fluent.Inc/fluent6.3.26/lnx86/2d/fluent.6.3.26: symbol lookup
    > error: libudf/lnx86/2d/libudf.so: undefined symbol: init
    >


    Which compilers do you use and how do you use them ?

    If you use the gnu compiliers, you should use

    g++ -c cpplib.cpp

    and then

    gcc cprogram.c cpplib.o

    Greetings, Uwe
     
    Uwe Schmitt, Sep 4, 2008
    #3
  4. Karel Van Laer

    Ian Collins Guest

    Uwe Schmitt wrote:
    >
    > Which compilers do you use and how do you use them ?
    >
    > If you use the gnu compiliers, you should use
    >
    > g++ -c cpplib.cpp
    >
    > and then
    >
    > gcc cprogram.c cpplib.o
    >
    > Greetings, Uwe


    That's very unlikely to work. The main program must be compiled and
    linked as C++.

    --
    Ian Collins.
     
    Ian Collins, Sep 4, 2008
    #4
  5. <snip>
    > I need to be able to mix C and C++.
    > The main program is written in C and needs to access C++ code.
    > To be more specific it's a user defined function in fluent, but this
    > should not be relevant.
    >
    > I've allready read that i need to use the extern "C" construction but i
    > don't seem to be doing it right.

    </snip>

    OK. Pardon a rank amature who only lurks here, BUT....
    This looks like backwards logic to me. I thought that
    'extern C' is a way for C++ code to call undecorated C code(?)
    Not the otherway around!
    Not that I have ever needed to face this, but I thought that C calling
    C++ code needs some type of wrapper?

    Confused?
    Drew
     
    northern_RATT, Sep 5, 2008
    #5
  6. On Sep 5, 12:52 pm, "northern_RATT" <> wrote:
    > <snip>> I need to be able to mix C and C++.
    > > The main program is written in C and needs to access C++ code.
    > > To be more specific it's a user defined function in fluent, but this
    > > should not be relevant.

    >
    > > I've allready read that i need to use the extern "C" construction but i
    > > don't seem to be doing it right.

    >
    > </snip>
    >
    > OK. Pardon a rank amature who only lurks here, BUT....
    > This looks like backwards logic to me. I thought that
    > 'extern C' is a way for C++ code to call undecorated C code(?)
    > Not the otherway around!
    > Not that I have ever needed to face this, but I thought that C calling
    > C++ code needs some type of wrapper?
    >
    > Confused?
    > Drew


    These kinds of problems are really annoying sometimes however
    unfortunately using both C and C++ are very common in real world (at
    least my world =P). I'm certainly wondering what would be the "best"
    practice for avoiding or even relaxing this kinds of issues.

    cheers,
    Alex Kim
     
    Alexander Dong Back Kim, Sep 5, 2008
    #6
  7. Alexander Dong Back Kim a écrit :
    > On Sep 5, 12:52 pm, "northern_RATT" <> wrote:
    >> <snip>> I need to be able to mix C and C++.

    > These kinds of problems are really annoying sometimes however
    > unfortunately using both C and C++ are very common in real world (at
    > least my world =P). I'm certainly wondering what would be the "best"
    > practice for avoiding or even relaxing this kinds of issues.


    Compile your C code with a c++ compiler :)
    Most c++ compiler support C99 unless you disable it in the command line.

    --
    Michael
     
    Michael DOUBEZ, Sep 5, 2008
    #7
  8. Karel Van Laer

    James Kanze Guest

    On Sep 4, 9:46 pm, Victor Bazarov <> wrote:
    > Ian Collins wrote:
    > > Uwe Schmitt wrote:
    > >> Which compilers do you use and how do you use them ?


    > >> If you use the gnu compiliers, you should use


    > >> g++ -c cpplib.cpp


    > >> and then


    > >> gcc cprogram.c cpplib.o


    > > That's very unlikely to work. The main program must be
    > > compiled and linked as C++.


    > So, more likely it should be


    > g++ -c cpplib.cpp
    > gcc -c cprogram.c
    > g++ cprogram.o cpplib.o -o cprogram


    If the main() is in cprogram.c, that still isn't guaranteed to
    work. main() must be compiled as C++. (But since not doing so
    is undefined behavior, it's possible that it works anyway, with
    some implementations.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Sep 5, 2008
    #8
  9. Karel Van Laer

    James Kanze Guest

    On Sep 5, 4:52 am, "northern_RATT" <> wrote:
    > <snip>> I need to be able to mix C and C++.
    > > The main program is written in C and needs to access C++
    > > code. To be more specific it's a user defined function in
    > > fluent, but this should not be relevant.


    > > I've allready read that i need to use the extern "C"
    > > construction but i don't seem to be doing it right.


    > </snip>


    > OK. Pardon a rank amature who only lurks here, BUT....
    > This looks like backwards logic to me. I thought that
    > 'extern C' is a way for C++ code to call undecorated C code(?)


    No. 'extern "C"' tells the compiler to use C linkage, period.
    A C++ function can be declared 'extern "C"', in which case, it
    uses C linkage (but is C++ in every other way), and can be
    called from a C program.

    The classical example is the function passed to things like
    pthread_create (Unix) or CreateThread (Windows); since this
    function is called from C code, it must be 'extern "C"'.

    > Not the otherway around!
    > Not that I have ever needed to face this, but I thought that C
    > calling C++ code needs some type of wrapper?


    And how would you implement the wrapper? If you can't call C++
    from C, you can't implement it in C, and if you implement it in
    C++, you couldn't call it from C.

    Typically, C++ code does require a wrapper, because it is using
    argument types which C can't handle; the wrapper takes care of
    any necessary type conversions. But thw wrapper itself is also
    C++.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Sep 5, 2008
    #9
  10. Karel Van Laer

    Uwe Schmitt Guest

    On 4 Sep., 21:10, Ian Collins <> wrote:
    > Uwe Schmitt wrote:
    >
    > > Which compilers do you use and how do you use them ?

    >
    > > If you use the gnu compiliers, you should use

    >
    > >      g++ -c cpplib.cpp

    >
    > > and then

    >
    > >      gcc cprogram.c cpplib.o

    >
    > > Greetings, Uwe

    >
    > That's very unlikely to work.  The main program must be compiled and
    > linked as C++.


    But all names cpplib.o are plain, because we used 'extern "C"' in
    'function()'s declaration. So the linker will see no C++ mangled
    symbolnames during linking.
    Did I miss something ? Why should I use C++ compiler for compiling and
    linking
    a C program with some object file which looks like a C-object file ?

    Greetings, Uwe
     
    Uwe Schmitt, Sep 5, 2008
    #10
  11. Uwe Schmitt <> writes:

    > On 4 Sep., 21:10, Ian Collins <> wrote:
    >> Uwe Schmitt wrote:
    >>
    >> > Which compilers do you use and how do you use them ?

    >>
    >> > If you use the gnu compiliers, you should use

    >>
    >> >      g++ -c cpplib.cpp

    >>
    >> > and then

    >>
    >> >      gcc cprogram.c cpplib.o

    >>
    >> > Greetings, Uwe

    >>
    >> That's very unlikely to work.  The main program must be compiled and
    >> linked as C++.

    >
    > But all names cpplib.o are plain, because we used 'extern "C"' in
    > 'function()'s declaration. So the linker will see no C++ mangled
    > symbolnames during linking.
    > Did I miss something ?


    The public symbols exported by cpplib.o and used in cprogram aren't
    the problem. The problem is that cpplib.o probably needs to link to
    libstdc++. That happens by default when you use g++, but not with
    gcc.

    sherm--

    --
    My blog: http://shermspace.blogspot.com
    Cocoa programming in Perl: http://camelbones.sourceforge.net
     
    Sherm Pendley, Sep 5, 2008
    #11
  12. Karel Van Laer

    James Kanze Guest

    On Sep 5, 7:29 pm, Uwe Schmitt <> wrote:
    > On 4 Sep., 21:10, Ian Collins <> wrote:
    > > Uwe Schmitt wrote:


    > > > Which compilers do you use and how do you use them ?
    > > > If you use the gnu compiliers, you should use


    > > > g++ -c cpplib.cpp


    > > > and then


    > > > gcc cprogram.c cpplib.o


    > > That's very unlikely to work. The main program must be compiled and
    > > linked as C++.


    > But all names cpplib.o are plain, because we used 'extern "C"' in
    > 'function()'s declaration. So the linker will see no C++ mangled
    > symbolnames during linking.


    So?

    > Did I miss something ? Why should I use C++ compiler for
    > compiling and linking a C program with some object file which
    > looks like a C-object file ?


    The C++ standard is quite clear: main() must be compiled as C++.
    Depending on the compiler, it might work if this isn't the case,
    or it might not, or somethings might work, and others not. In
    particular, with some compilers, there's a very good chance that
    static variables won't be initialized correctly if main isn't
    compiled as C++.

    And mangling really has not got much to do with the problem.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Sep 5, 2008
    #12
  13. Karel Van Laer

    James Kanze Guest

    On Sep 5, 7:35 pm, Sherm Pendley <> wrote:
    > Uwe Schmitt <> writes:
    > > On 4 Sep., 21:10, Ian Collins <> wrote:
    > >> Uwe Schmitt wrote:
    > >> > Which compilers do you use and how do you use them ?


    > >> > If you use the gnu compiliers, you should use


    > >> > g++ -c cpplib.cpp


    > >> > and then


    > >> > gcc cprogram.c cpplib.o


    > >> That's very unlikely to work. The main program must be
    > >> compiled and linked as C++.


    > > But all names cpplib.o are plain, because we used 'extern
    > > "C"' in 'function()'s declaration. So the linker will see no
    > > C++ mangled symbolnames during linking. Did I miss
    > > something ?


    > The public symbols exported by cpplib.o and used in cprogram
    > aren't the problem. The problem is that cpplib.o probably
    > needs to link to libstdc++. That happens by default when you
    > use g++, but not with gcc.


    The problem is also that static variables have to be
    initialized; some compilers do this by generating special code
    in main. Of course, if main wasn't compiled with a C++
    compiler, it won't have that special code.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Sep 5, 2008
    #13
  14. Karel Van Laer

    Jerry Coffin Guest

    In article <48c0dbfe$0$17346$>,
    says...

    [ ... ]

    > Most c++ compiler support C99 unless you disable it in the command line.


    Really? All the C++ compilers I have handy seem to reject the following
    perfectly legal bit of C99 code:

    union {
    char birthday[9];
    int age;
    float weight;
    } people = { .age = 14 };

    Even Comeau (which will accept it as C99 code) rejects it as C++ code
    (quite rightly, I might add, since it's ill formed C++ code, and I don't
    believe C++ 0x will allow it either).

    Every other compiler I have handy (Microsoft, Digital Mars, gnu) rejects
    it as either C or C++. gnu has a '-std=c99' flag, but appears to
    implement little enough of C99 that it doesn't accept this even with
    that flag.

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Sep 6, 2008
    #14
  15. Karel Van Laer

    Uwe Schmitt Guest

    On 5 Sep., 20:25, James Kanze <> wrote:
    > On Sep 5, 7:35 pm, Sherm Pendley <> wrote:
    >
    >
    >
    > > Uwe Schmitt <> writes:
    > > > On 4 Sep., 21:10, Ian Collins <> wrote:
    > > >> Uwe Schmitt wrote:
    > > >> > Which compilers do you use and how do you use them ?
    > > >> > If you use the gnu compiliers, you should use
    > > >> >      g++ -c cpplib.cpp
    > > >> > and then
    > > >> >      gcc cprogram.c cpplib.o
    > > >> That's very unlikely to work.  The main program must be
    > > >> compiled and linked as C++.
    > > > But all names cpplib.o are plain, because we used 'extern
    > > > "C"' in 'function()'s declaration. So the linker will see no
    > > > C++ mangled symbolnames during linking.  Did I miss
    > > > something ?

    > > The public symbols exported by cpplib.o and used in cprogram
    > > aren't the problem. The problem is that cpplib.o probably
    > > needs to link to libstdc++. That happens by default when you
    > > use g++, but not with gcc.

    >
    > The problem is also that static variables have to be
    > initialized; some compilers do this by generating special code
    > in main.  Of course, if main wasn't compiled with a C++
    > compiler, it won't have that special code.
    >
    > --
    > James Kanze (GABI Software)             email:
    > hing nConseils en informatique orientée objet/
    >                    Beratung in objektorientierter Datenverarbeitung
    > 9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


    thanks, I learned something new :)

    Greetings, Uwe
     
    Uwe Schmitt, Sep 6, 2008
    #15
  16. Jerry Coffin <> writes:

    > In article <48c0dbfe$0$17346$>,
    > says...
    >
    > [ ... ]
    >
    >> Most c++ compiler support C99 unless you disable it in the command line.

    >
    > Really? All the C++ compilers I have handy seem to reject the following
    > perfectly legal bit of C99 code:
    >
    > union {
    > char birthday[9];
    > int age;
    > float weight;
    > } people = { .age = 14 };
    >
    > Even Comeau (which will accept it as C99 code) rejects it as C++ code
    > (quite rightly, I might add, since it's ill formed C++ code, and I don't
    > believe C++ 0x will allow it either).
    >
    > Every other compiler I have handy (Microsoft, Digital Mars, gnu) rejects
    > it as either C or C++. gnu has a '-std=c99' flag, but appears to
    > implement little enough of C99 that it doesn't accept this even with
    > that flag.


    Recent versions of gcc accept it.

    --
    Ben.
     
    Ben Bacarisse, Sep 6, 2008
    #16
  17. Karel Van Laer

    Ian Collins Guest

    Ben Bacarisse wrote:
    > Jerry Coffin <> writes:
    >
    >> In article <48c0dbfe$0$17346$>,
    >> says...
    >>
    >> [ ... ]
    >>
    >>> Most c++ compiler support C99 unless you disable it in the command line.

    >> Really? All the C++ compilers I have handy seem to reject the following
    >> perfectly legal bit of C99 code:
    >>
    >> union {
    >> char birthday[9];
    >> int age;
    >> float weight;
    >> } people = { .age = 14 };
    >>
    >> Even Comeau (which will accept it as C99 code) rejects it as C++ code
    >> (quite rightly, I might add, since it's ill formed C++ code, and I don't
    >> believe C++ 0x will allow it either).
    >>
    >> Every other compiler I have handy (Microsoft, Digital Mars, gnu) rejects
    >> it as either C or C++. gnu has a '-std=c99' flag, but appears to
    >> implement little enough of C99 that it doesn't accept this even with
    >> that flag.

    >
    > Recent versions of gcc accept it.
    >

    gcc also accepts VLAs, but I doubt any other C++ compiler would.

    --
    Ian Collins.
     
    Ian Collins, Sep 6, 2008
    #17
  18. Karel Van Laer

    Jerry Coffin Guest

    In article <>, says...

    [ ... ]

    > Recent versions of gcc accept it.


    I'm glad to hear that. What I was using isn't exactly current, but it's
    not terribly old either -- it's good to hear that they're apparently
    making a real attempt at C99 compliance (finally...)

    --
    Later,
    Jerry.

    The universe is a figment of its own imagination.
     
    Jerry Coffin, Sep 7, 2008
    #18
  19. Jerry Coffin a écrit :
    > In article <48c0dbfe$0$17346$>,
    > says...
    >
    > [ ... ]
    >
    >> Most c++ compiler support C99 unless you disable it in the command line.

    >
    > Really? All the C++ compilers I have handy seem to reject the following
    > perfectly legal bit of C99 code:
    >
    > union {
    > char birthday[9];
    > int age;
    > float weight;
    > } people = { .age = 14 };
    >


    True. I have overly generalized.
    I was thinking of VLAs which tends to creep in so often. This code is
    however accepted by my IAR c++ compiler.

    More compliant c++ compiler will hopefully reject this code. But I guess
    one could tweak them into accepting it.

    --
    Michael
     
    Michael DOUBEZ, Sep 8, 2008
    #19
  20. Jerry Coffin a écrit :
    > In article <48c0dbfe$0$17346$>,
    > says...
    >
    > [ ... ]
    >
    >> Most c++ compiler support C99 unless you disable it in the command line.

    >
    > Really? All the C++ compilers I have handy seem to reject the following
    > perfectly legal bit of C99 code:
    >
    > union {
    > char birthday[9];
    > int age;
    > float weight;
    > } people = { .age = 14 };
    >


    True. I have overly generalized.
    I was thinking of VLAs which tends to creep in so often. This code is
    however accepted by my IAR c++ compiler.

    More compliant c++ compiler will hopefully reject this code. But I guess
    one could tweak them into accepting it.

    --
    Michael
     
    Michael DOUBEZ, Sep 8, 2008
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Newsgroup - Ann
    Replies:
    1
    Views:
    358
    John Harrison
    Jul 5, 2003
  2. josef angermeier

    Re: extern function declaration

    josef angermeier, Jul 17, 2003, in forum: C++
    Replies:
    0
    Views:
    393
    josef angermeier
    Jul 17, 2003
  3. Andrey Tarasevich

    Re: extern function declaration

    Andrey Tarasevich, Jul 16, 2003, in forum: C++
    Replies:
    0
    Views:
    421
    Andrey Tarasevich
    Jul 16, 2003
  4. Thomas Matthews
    Replies:
    5
    Views:
    2,459
    tom_usenet
    Aug 2, 2004
  5. Andre
    Replies:
    5
    Views:
    544
    Keith Thompson
    Jul 17, 2012
Loading...

Share This Page