Thread: help with error when compiling a C program with g++

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    31

    help with error when compiling a C program with g++

    Hello,

    I have a C program (using OpenGL) that compiles and runs quite well with gcc. Now, to expand it I need to use a library that's written in C++, of which I know nothing.
    I tried simply compiling my code with g++, to see if I could "fake" the C++, i.e. not change my existing code and simply use it when I need to call this new library.

    I got only one error. If I comment out the function where the error is, everything seems to compile and run quite well. The thing is I do not understand the error, so I hope someone could give me a hint.

    First and foremost, do you guys see any risk in doing what I intend to do?

    Second, I put g++ instead of gcc in my Makefile, and changed my code to *.cpp. When I make it, I get this error:

    visuals.c:465: error: invalid conversion from 'void*' to 'unsigned char*'

    The code with the error is below. The line 465 of the error is

    Code:
    pixels = malloc(3*width*height);
    Function with the error
    Code:
    int capture_to_ppm(void)
    {
    	int width, height, colorDepth, maxColorValue,y;
    	unsigned char	*pixels;
    	int fd;
    	char sbuf[256]; /* for sprintf() */
    
    	/* open output file: you can name it as you like */
    	fd = open(picfile,O_CREAT|O_TRUNC|O_WRONLY,
    					  S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
    	if(fd == -1) return -1;
    
    	/* width & height of the window */
    	width = glutGet(GLUT_WINDOW_WIDTH);
    	height = glutGet(GLUT_WINDOW_HEIGHT);
    
    	/* maxColorValue is 255 in most cases... */
    	colorDepth = glutGet(GLUT_WINDOW_RED_SIZE);
    	maxColorValue = (1 << colorDepth) - 1;
    
    	/* allocate pixels[]: 3 is for RGB */
    	pixels = malloc(3*width*height);
    	if( !pixels ) return -2;
    
    	/* get RGB values from the frame buffer into pixels[] */
    	glReadBuffer(GL_FRONT); /* if you are using "double buffer" */
    	glReadPixels(0,0,width,height,GL_RGB,GL_UNSIGNED_BYTE,pixels);
    
    	/* write ppm file header */
    	sprintf(sbuf,"P6 %d %d %d\n",width,height,maxColorValue);
    	write(fd,sbuf,strlen(sbuf));
    	
    	/* write ppm RGB data: we must invert upside down */
    	for(y = height-1; y >= 0; --y) {
    		write(fd, pixels+3*width*y, 3*width);
    	}	
    
    	close(fd);
    	free(pixels);
    	return 0;
    }
    Thank you very much for any help,

    mc61

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Unlike C, C++ does not allow for implicit conversion from void* to other pointer types. You have to explicitly cast void* to unsigned char*.
    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

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    31
    You mean like this?

    Code:
    pixels = (unsigned char*)malloc(3*width*height);
    Sorry if I abuse your kindness with one more thing, but then I take it that you do not see any danger with my strategy?

    Thanks for your help,

    mc61

  4. #4
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Could you write a small wrapper for the lib you need - wrapper that will translate all C++ calls to C
    Compile only this wrapper library by g++ to build some lib file - and link this file to your project that will be still compiled as C by gcc?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You mean like this?
    Yes.

    Sorry if I abuse your kindness with one more thing, but then I take it that you do not see any danger with my strategy?
    It is probably okay, but you might want to read How to mix C and C++.
    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

  6. #6
    Registered User
    Join Date
    Dec 2007
    Posts
    31
    laserlight: thanks so much for your help and for pointing to the article on mixing C and C++. I'll definitely read it.

    vart: thanks for the suggestion, but I am afraid I have no idea how to do that... If you know of something I could read and learn, I am all ears!

  7. #7
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    What vart means is -- there are two ways to solve this problem. Either compile it as C++, with casts everywhere or something of the like, or use a wrapper of some sort.

    As an example wrapper, this lets you call a C++ function from C. (Note: with this method, you could continue compiling your program as C.)
    Code:
    // this is compiled as C++
    
    void cpp_function() {
        // ...
    }
    
    extern "C" {
    
    void c_function() {
        cpp_function();
    }
    
    }
    Basically, C++ functions can be wrapped with extern "C", and then they're treated as C ones. If only one function is extern "C", you can leave out the curly braces, I think.
    Code:
    extern "C"
    void c_function() {
        // ...
    }
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  8. #8
    Registered User
    Join Date
    Dec 2007
    Posts
    31
    dwks, vart, laserlight,

    Thank you very much for all your help. I think I understand now what a wrapper is. Incidentally, after I replied to vart's post I read the article that laserlight suggested, and thus I discovered all this extern "C" stuff. I just have to try it now :-)

    Thank again. This forum is amazing!

    mc61

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help with my program...
    By Noah in forum C Programming
    Replies: 2
    Last Post: 03-11-2006, 07:49 PM
  2. adding an #include stops my program from compiling
    By angelscars in forum C++ Programming
    Replies: 5
    Last Post: 11-11-2005, 05:24 PM
  3. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  4. Replies: 3
    Last Post: 04-19-2004, 08:09 AM
  5. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM