Thread: Extern "C" problem

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    24

    Extern "C" problem

    Hello,

    I'm a a pretty new programmer just beginning to play around with C and C++. I use Linux and am compiling with gcc/g++ 4.3.2 however I'm coming across a strange problem that I just can't resolve.

    I'm trying to write a simple program to just see the possibilities of calling C++ code from C. The main() function is in C :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include "cpp_main.h"
    
    /*
     * 
     */
    int main(int argc, char** argv) {
        int return_value;
        return_value = cpp_main(argc,argv);
        return (return_value);
    }
    The function cpp_main() is written in C++, and is in file cpp_main.cpp :

    Code:
    #include "cpp_main.h"
    //#include "testclass.h"
    
    //int cpp_main(int argc, char** argv);
    /*extern "C" {
        int cpp_main(int argc, char** argv);
    }*/
    
    int cpp_main(int argc, char** argv){
        char *testtext = "Some Test Text to display.\n";
        //TestClass::WriteMessage(testtext);
        
        return(0);
    }

    And cpp_main.h is :

    Code:
    //#ifndef _CPP_MAIN_H
    //#define _CPP_MAIN_H
    
    // Declare cpp_main() function
    //int cpp_main(int argc, char** argv);
    extern "C" {
       void cpp_main(int argc, char** argv);
    };
    
    //#endif	/* _CPP_MAIN_H */

    However when I try to build the executable I receive this error :

    cpp_main.h:6: error: expected identifier or ‘(’ before string constant


    gcc is telling me there is something wrong with extern "C"... ?!?!!?

    If I take the line from the header file and paste it directly into cpp_main.cpp everything compiles and links ok... but why won't it work with the header file ?

    Any help is much appreciated

    Steve

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The C code has no idea what extern "C" means. You need this:

    Code:
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /* Your C-callable prototypes */
    
    #ifdef __cplusplus
    }
    #endif
    Also, do NOT use // style comments in this header. It's shared between C and C++ code, and C has no idea what a // comment is.

    EDIT: Oops. I was using #ifndef where it should have been #ifdef.
    Last edited by brewbuck; 06-09-2009 at 10:55 PM.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    It's a C++ invention to use C name-mangling. To be both C and C++ compatible:
    Code:
    #ifdef __cplusplus
    extern "C" {
    #endif
    gg

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by brewbuck View Post
    Also, do NOT use // style comments in this header. It's shared between C and C++ code, and C has no idea what a // comment is.
    I use // all the time and neither me nor my programs know a note of C++.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by MK27 View Post
    I use // all the time and neither me nor my programs know a note of C++.
    It was added to C with C99.

  6. #6
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by MK27 View Post
    I use // all the time and neither me nor my programs know a note of C++.
    Like tabstop says, it's support in C99, but there are still a lot of older compilers out there. If your header is general purpose, meant to be released to the wild, it's not a good idea to use the newer style comments.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  7. #7
    Registered User
    Join Date
    Jun 2009
    Posts
    24
    Quote Originally Posted by brewbuck View Post
    The C code has no idea what extern "C" means. You need this:

    Code:
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    /* Your C-callable prototypes */
    
    #ifdef __cplusplus
    }
    #endif
    Also, do NOT use // style comments in this header. It's shared between C and C++ code, and C has no idea what a // comment is.

    EDIT: Oops. I was using #ifndef where it should have been #ifdef.
    OK, well as in my original post, can you explain why this compiles :

    Code:
    //#include "cpp_main.h"
    //#include "testclass.h"
    //=========================================
    // Include the header in cpp_main.cpp
    //=========================================
    //int cpp_main(int argc, char** argv);
    extern "C" {
        int cpp_main(int argc, char** argv);
    }
    
    int cpp_main(int argc, char** argv){
        char *testtext = "Some Test Text to display.\n";
        //TestClass::WriteMessage(testtext);
        
        return(0);
    }
    Yet if I separate decelerations into a header file, this does NOT compile, giving the error I originally stated :

    cpp_main.h
    Code:
    // Declare cpp_main() function
    //int cpp_main(int argc, char** argv);
    extern "C" {
       int cpp_main(int argc, char** argv);
    };
    cpp_main.cpp
    Code:
    #include "cpp_main.h"
    
    
    int cpp_main(int argc, char** argv){
        char *testtext = "Some Test Text to display.\n";
        //TestClass::WriteMessage(testtext);
        
        return(0);
    }
    I'm using gcc and it has the capability to determine the source type (C or C++) from the file extension and passes it to the appropriate compiler in the toolchain, therefore I do not believe it's a problem due to trying to compile C++ with a C compiler.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Recall that once you separated the code into a header, you included the header in a C source file.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Jun 2009
    Posts
    24
    Quote Originally Posted by laserlight View Post
    Recall that once you separated the code into a header, you included the header in a C source file.
    If you mean I included if in cpp_main.cpp, then no, cpp_main is a C++ file - and what I mean by this is that the file has the extension .cpp so gcc will interpret that file as a C++ file.

    Or do you mean that I included a .h file in a C++ source file - .h files a C headers and shouldn't be used in C++ ?

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    So, what is the name of the file that contains this code?
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include "cpp_main.h"
    
    /*
     * 
     */
    int main(int argc, char** argv) {
        int return_value;
        return_value = cpp_main(argc,argv);
        return (return_value);
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Jun 2009
    Posts
    24
    Quote Originally Posted by laserlight View Post
    So, what is the name of the file that contains this code?
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include "cpp_main.h"
    
    /*
     * 
     */
    int main(int argc, char** argv) {
        int return_value;
        return_value = cpp_main(argc,argv);
        return (return_value);
    }
    OK.. point taken.. thanks laserlight .. and apologies too !

    OK, now I've removed the #include cpp_main.h from the main() file and compiled it.. expecting it to throw a new error i.e. cpp_main not found... but no.. the compiler found it ! So what's the point of declaring functions then ? (You'll have to forgive me as I'm a relatively new C programmer)

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by CodeBugs
    OK, now I've removed the #include cpp_main.h from the main() file and compiled it.. expecting it to throw a new error i.e. cpp_main not found... but no.. the compiler found it ! So what's the point of declaring functions then ? (You'll have to forgive me as I'm a relatively new C programmer)
    The point is to declare the function so that its return type and parameter types are clearly spelt out rather than assumed to be int (which is what happens if the C compiler is unable to find a relevant function declaration at the point of the function call).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. extern const?Please help
    By huwan in forum C++ Programming
    Replies: 10
    Last Post: 08-12-2008, 04:53 AM
  2. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM
  3. Replies: 16
    Last Post: 10-29-2006, 05:04 AM
  4. problem with extern variables
    By crash88 in forum C Programming
    Replies: 11
    Last Post: 05-05-2006, 01:44 PM
  5. Odd Problem with Linking
    By jamez05 in forum C++ Programming
    Replies: 6
    Last Post: 09-21-2005, 01:49 PM