Thread: calling C functions from C++ code

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    29

    calling C functions from C++ code

    I've been having issues with this lately. I have written a .h file and a .c file, both with c code. I tried to include them in my project by following this tutorial:

    [32] How to mix C and C++ ..Updated!.., C++ FAQ

    More specifically:

    Code:
     
     #ifdef __cplusplus
     extern "C" {
     #endif
    and

    Code:
     #ifdef __cplusplus
     }
     #endif

    surrouding the code in my .h file, and then in my c++ code I #include like this:

    Code:
    extern "C" {
    
    #include "myheader.h"
    
    
    }
    When I surround the function call in an extern "C" block, it gives me an error "linkage specification not allowed". When I take the extern "C" surrounding the function call, I am not sure what I am missing, but when I try to run my code, it finds the .h file just fine but gives me an error that the function called has a prototype but no body. Am I supposed to compile the C code separately? Any idea?

  2. #2
    Registered User
    Join Date
    Oct 2011
    Posts
    29
    I am using Visual C++ 2010 express, by the way, which kinda complicates things, because I can't just include a .c file in my project...

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    The extern "C" block must surround the C++ functions you want to be able to access from C. Just surrounding an include file will not work. Normally you would not surround an include file with a extern "C" block.
    Code:
    /* Your header file. */
    
    #include "yourheader.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void yourCPPfunction();
    
    #ifdef __cplusplus
    }
    #endif
    I am using Visual C++ 2010 express, by the way, which kinda complicates things, because I can't just include a .c file in my project...
    Why not? As long as the file has a .c extension it will be compiled as a C program. Also note, you don't need the extern C block if you are compiling with a C++ compiler.


    Jim

  4. #4
    Registered User
    Join Date
    Oct 2011
    Posts
    29
    Quote Originally Posted by jimblumberg View Post
    The extern "C" block must surround the C++ functions you want to be able to access from C. Just surrounding an include file will not work. Normally you would not surround an include file with a extern "C" block.
    Code:
    /* Your header file. */
    
    #include "yourheader.h"
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void yourCPPfunction();
    
    #ifdef __cplusplus
    }
    #endif

    Why not? As long as the file has a .c extension it will be compiled as a C program. Also note, you don't need the extern C block if you are compiling with a C++ compiler.


    Jim
    Just to be clear, that would be my C++ header file, right? If so, then basically do you need to prototype the functions again, but in an extern "C" block?

    Also, yeah I was wrong. I just tried and successfully added the .c file and its header. It's still not finding the function body, though.

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Post your current code that illustrates the problem, along with any error messages you receive when you compile that code, exactly as they appear in your development environment.

    The only functions that will need to be enclosed in the extern C block will be C++ functions that your C file tries to access.

    Jim

  6. #6
    Registered User
    Join Date
    Oct 2011
    Posts
    29
    Quote Originally Posted by jimblumberg View Post
    Post your current code that illustrates the problem, along with any error messages you receive when you compile that code, exactly as they appear in your development environment.

    The only functions that will need to be enclosed in the extern C block will be C++ functions that your C file tries to access.

    Jim
    Oh, it's the other way around, my C++ file has to access C functions, all written by me. It's a lot of code, though. Give me a minute and I'll get a paraphrased version posted.

    But the error is:

    error C2129: static function 'void video_decode(const char *,const char *)' declared but not defined

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    It sounds like you merely did not define, or incorrectly defined, the function in the 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

  8. #8
    Registered User
    Join Date
    Oct 2011
    Posts
    29
    Quote Originally Posted by laserlight View Post
    It sounds like you merely did not define, or incorrectly defined, the function in the source file.
    This is my exact function header on my .h file:

    Code:
    static void video_decode(const char *outfile, const char *infile);
    and on my .c file:

    Code:
    static void video_decode(const char *outfile, const char *infile){
        AVCodec *codec;
        AVCodecContext *c = NULL;
        int movieframe, got_picture, len;
        FILE *f;
        AVFrame *picture;
        uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
        char buf[1024];
        AVPacket avpkt;
    
        av_init_packet(&avpkt);
    
    
        memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);
    
        printf("Decoding in progress\n");
    
        codec = avcodec_find_decoder(CODEC_ID_H263);
        if(!codec){
            fprintf(stderr, "codec not found\n");
            exit(1);
        }
    
        c = avcodec_alloc_context();
        picture = avcodec_alloc_frame();
    
        if(codec->capabilities & CODEC_CAP_TRUNCATED){
            c->flags|= CODEC_FLAG_TRUNCATED;
        }
    
        if(avcodec_open(c,codec) < 0){
            fprintf(stderr, "could not open codec\n");
            exit(1);
        }
    
        f = fopen(infile, "rb");
        if(!f){
            fprintf(stderr, "infile not found\n");
            exit(1);
        }
    
        movieframe = 0;
        for(;;){
            avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
            if(avpkt.size == 0)
                break;
    
            avpkt.data = inbuf;
            while(avpkt.size > 0){
                len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
                if(len < 0){
                    fprintf(stderr, "Error decoding frame\n");
                    exit(1);
                }
                if(got_picture){
                    printf("saving frame %3d\n", movieframe);
                    fflush(stdout);
    
                    #ifdef WIN32
                    sprintf_s(buf, sizeof(buf), outfile, movieframe);
                    #else
                    snprintf(buf, sizeof(buf), outfilename, frame);
                    #endif
                    pgm_save(picture->data[0], picture->linesize[0], c->width, c->height, buf);
                    movieframe++;
                }
                avpkt.size -= len;
                avpkt.data += len;
            }
        }
    
        avpkt.data = NULL;
        avpkt.size = 0;
        len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
        if(got_picture){
            printf("saving last frame\n");
            fflush(stdout);
    
            #ifdef WIN32
            sprintf_s(buf, sizeof(buf), outfile, movieframe);
            #else
            snprintf(buf, sizeof(buf), outfile, movieframe);
            #endif
            pgm_save(picture->data[0], picture->linesize[0], c->width, c->height, buf);
            movieframe++;
        }
    
        fclose(f);
    
        avcodec_close(c);
        av_free(c);
        av_free(picture);
        printf("\n");
    
    }
    verbatim as they are... What can be wrong?

  9. #9
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Why are you defining your function static? Do you really only want to call this function from another function in the same file. The static prefix says you don't want other files to be able to see this function. I recommend dropping the static, in both the header and the implementation. See this link for another explanation: static functions

    Jim

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Why did you declare the function static? Normally, a static function would be defined in a source file only, because it is implementation detail that should be kept to that source file. In fact, in C++, we would prefer to define the non-member function in an unnamed namespace instead of declaring it static.
    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
    Aug 2010
    Location
    Poland
    Posts
    733
    Remove the 'static' keyword.

  12. #12
    Registered User
    Join Date
    Oct 2011
    Posts
    29
    Oh, that makes sense. Thanks for the link. Yeah, it's not really my code, I got it from a website and was trying it out. I guess for their purposes it was static, but it makes sense that it wouldn't work now. I'll fix that and see if it works.

    Thanks.

  13. #13
    Registered User
    Join Date
    Oct 2011
    Posts
    29
    Problem now seems to be that I don't know hot to add a .c source file to my visual c++ project (which is using precompiled headers. It's part of a larger project so I better not fool with that). Only choice I've got is to make it work. Any ideas? Seems when I try to #include "stdafx.h", which I have to do in both my .h and .c files because otherwise it gives me the precompiled header error, I get this:

    Code:
    precompiled header file is from a previous version of the compiler, or the precompiled header is C++ and you are using it from C (or vice versa)
    any ideas?

  14. #14
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    Do not include stdafx.h in your C file.

    Jim

  15. #15
    Registered User
    Join Date
    Oct 2011
    Posts
    29
    Quote Originally Posted by jimblumberg View Post
    Do not include stdafx.h in your C file.

    Jim
    That was the first thing I tried. But it gave me this error, which now I will post verbatim:

    Code:
    precompiled header file is from a previous version of the compiler, or the precompiled header is C++ and you are using it from C (or vice versa)
    error comes up as being in the .c source file.

    It's weird, because I did not have stdafx.h included... if anything it should complain about that.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Calling functions
    By cda67 in forum C Programming
    Replies: 2
    Last Post: 10-14-2011, 11:56 PM
  2. Help calling and using a functions
    By method in forum Windows Programming
    Replies: 0
    Last Post: 07-08-2006, 04:08 PM
  3. calling functions & assembly code
    By Micko in forum C++ Programming
    Replies: 1
    Last Post: 02-25-2004, 03:27 PM
  4. calling functions::
    By Yoshi in forum C++ Programming
    Replies: 1
    Last Post: 12-13-2002, 02:34 PM
  5. Functions calling themselves...?
    By mikebrewsj in forum C++ Programming
    Replies: 10
    Last Post: 01-18-2002, 12:09 AM

Tags for this Thread