Thread: undefined reference to function in class error

  1. #1
    Registered User
    Join Date
    Nov 2004
    Posts
    69

    undefined reference to function in class error

    Yea for some reason I keep getting this error.

    ERROR
    Code:
    main.o: In function `Render()':
    main.cpp:(.text+0xa0): undefined reference to `CControllerFunc::buttonstatus(int
    )'
    collect2: ld returned 1 exit status
    make: *** [gui_class_tut.elf] Error 1
    Here's all the files.

    main.cpp
    Code:
    #include <pspdisplay.h>
    #include <pspkernel.h>
    #include <pspdebug.h>
    #include <pspctrl.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdio.h>
    //#include "main.h"
    #include "controller.h"
    //#include "menu.h"
    
    CControllerFunc CController;
    
    //#include "menu.h"
    //Define module info for this program.
    PSP_MODULE_INFO("BLADECONTROLLERTUT", 0, 1, 1);
    //Define dprint as pspDebugScreenPrintf.
    #define dprint	pspDebugScreenPrintf 
    //Define done integer.
    int done = 0;
    //Define variable called pad with controller data type.
    //Define exit_callback function.
    int exit_callback(int arg1, int arg2, void *common)
    {
    	done = 1;
    	return 0;
    }
    //Define CallbackThread function.
    int CallbackThread(SceSize args, void *argp)
    {
    	int cbid;
    	cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
    	sceKernelRegisterExitCallback(cbid);
    	sceKernelSleepThreadCB();
    	return 0;
    }
    //Define Render function. Contains main code
    void Render(){
    //Reads the controller buffer.
    sceCtrlReadBufferPositive(&CController.pad, 1);
    dprint("-STATUS-\t\t-BUTTON-\n\n");
    if(CController.buttonstatus(PSP_CTRL_CROSS)){
    	dprint("-DOWN-\t\t-CROSS-\n\n");
    	} else {
    	dprint("- UP -\t\t-CROSS-\n\n");
    	}
    }
    //Define SetupCallbacks function
    int SetupCallbacks(void)
    {
    	int thid = 0;
    	thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
    	if(thid >= 0)
    	{
    		sceKernelStartThread(thid, 0, 0);
    	}
    	return thid;
    }
    //Define main function
    int main(void)
    {
    	pspDebugScreenInit();//Intialize debug screen mode.
    	SetupCallbacks();
    	sceCtrlSetSamplingCycle(0);//Set controller sampling cycle
    	sceCtrlSetSamplingMode(1);//Set controller sampling mode
    	pspDebugScreenSetTextColor(0x82DCFD00);//Set debug text color
    	while(!done){//While the program isn't done
    		sceDisplayWaitVblankStart();//Wait until the screen is done clearing
    		Render();//Render
    		pspDebugScreenClear();//Clear the screen
    	}
    	sceKernelExitGame();//Exit game
    	return 0;//Return 0 since main is an int type
    }
    controller.cpp
    Code:
    #include "controller.h"
    
    int CControllerFunc::buttonstatus(int Button)
    {
    
    	if(pad.Buttons & Button){
    	pressed = 1;
    	} else {
    	pressed = 0;
    	}
    	return pressed;
    
    }

    controller.h
    Code:
    #ifndef CONTROLLER_H
    #define CONTROLLER_H
    
    class CControllerFunc
    {
    
    public:
    
    	CControllerFunc();
    	~CControllerFunc();
    	int buttonstatus(int Button);
    	SceCtrlData pad;
    
    private:
    
    	int pressed;
    	
    	
    };
    
    //Constructor of CControllerFunc
    
    CControllerFunc::CControllerFunc()
    {
    pressed = 0;
    }
    
    //Deconstructor of CControllerFunc - Takes no action
    
    CControllerFunc::~CControllerFunc()
    {
    
    
    }
    #endif
    Any ideas? Thanks for everything

  2. #2
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    You have to compile and link controller.cpp along with main.cpp so that the function definition is compiled and linked.

  3. #3
    Registered User
    Join Date
    Nov 2004
    Posts
    69
    Quote Originally Posted by Daved
    You have to compile and link controller.cpp along with main.cpp so that the function definition is compiled and linked.
    Well controller.h is included into main.cpp, so wouldn't that work? If not give me an example.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Each source file (cpp file) must be compiled, and then after each source file is compiled, they are all linked together. If you have a makefile, you must add controller.cpp to the makefile. If you have a project, then you must add controller.cpp to the project. If you build on the command line, then you must add controller.cpp to the command line.

    If you have trouble, tell us what compiler and/or IDE you are using and show the commands (if any) you are using to build the program.

  5. #5
    Registered User
    Join Date
    Nov 2004
    Posts
    69
    Quote Originally Posted by Daved
    Each source file (cpp file) must be compiled, and then after each source file is compiled, they are all linked together. If you have a makefile, you must add controller.cpp to the makefile. If you have a project, then you must add controller.cpp to the project. If you build on the command line, then you must add controller.cpp to the command line.

    If you have trouble, tell us what compiler and/or IDE you are using and show the commands (if any) you are using to build the program.
    Yea, I am using a make file, and I am using Cygwin, because this a linux based compiler and this is what's in it :

    Code:
    TARGET = gui_class_tut
    OBJS = main.o
    
    INCDIR = 
    CFLAGS = -O2 -G0 -Wall
    CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
    ASFLAGS = $(CFLAGS)
    
    LIBDIR =
    LDFLAGS =
    
    EXTRA_TARGETS = EBOOT.PBP
    PSP_EBOOT_TITLE = GUI Class Tut
    PSPSDK=$(shell psp-config --pspsdk-path)
    include $(PSPSDK)/lib/build.mak

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    It's been awhile since I've even looked at a makefile, but it looks like something is missing. You will need to add controller.o to the OBJS, but I don't see where it specifies all the source files. Maybe in build.mak?

  7. #7
    Registered User
    Join Date
    Nov 2004
    Posts
    69
    Quote Originally Posted by Daved
    It's been awhile since I've even looked at a makefile, but it looks like something is missing. You will need to add controller.o to the OBJS, but I don't see where it specifies all the source files. Maybe in build.mak?
    build.mak is just part of the sdk itself. Lemme see if adding it to the OBJS works.

  8. #8
    Registered User
    Join Date
    Nov 2004
    Posts
    69
    Ok, now I changed the make file to

    Code:
    TARGET = gui_class_tut
    OBJS = main.o
    OBJS = controller.o
    
    INCDIR = 
    CFLAGS = -O2 -G0 -Wall
    CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
    ASFLAGS = $(CFLAGS)
    
    LIBDIR =
    LDFLAGS =
    
    EXTRA_TARGETS = EBOOT.PBP
    PSP_EBOOT_TITLE = GUI Class Tut
    PSPSDK=$(shell psp-config --pspsdk-path)
    include $(PSPSDK)/lib/build.mak
    but now I get this error

    Code:
    In function `_main': undefined reference to `main'
    collect2: ld returned 1 exit status
    This seems..........ridiculous

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    I would think it should be one definition of OBJS:
    Code:
    OBJS = main.o controller.o

  10. #10
    Registered User
    Join Date
    Nov 2004
    Posts
    69
    Quote Originally Posted by Daved
    I would think it should be one definition of OBJS:
    Code:
    OBJS = main.o controller.o
    That works better, but I still get alot of errors

    Code:
    controller.o: In function `CControllerFunc::CControllerFunc()':
    controller.cpp:(.text+0x0): multiple definition of `CControllerFunc::CController
    Func()'
    main.o:main.cpp:(.text+0x0): first defined here
    controller.o: In function `CControllerFunc::CControllerFunc()':
    controller.cpp:(.text+0x8): multiple definition of `CControllerFunc::CController
    Func()'
    main.o:main.cpp:(.text+0x8): first defined here
    controller.o: In function `CControllerFunc::~CControllerFunc()':
    controller.cpp:(.text+0x10): multiple definition of `CControllerFunc::~CControll
    erFunc()'
    main.o:main.cpp:(.text+0x10): first defined here
    controller.o: In function `CControllerFunc::~CControllerFunc()':
    controller.cpp:(.text+0x18): multiple definition of `CControllerFunc::~CControll
    erFunc()'
    main.o:main.cpp:(.text+0x18): first defined here
    collect2: ld returned 1 exit status
    make: *** [gui_class_tut.elf] Error 1

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    Since both controller.cpp and main.cpp are including controller.h, the compiler compiles the functions in controller.h both times, and you get errors in the linking because they are defined multiple times. So the definitions for those functions (CControllerFunc::CControllerFunc() and CControllerFunc::~CControllerFunc()) in your header file should go in the controller.cpp file instead, or they should be moved inside the class declaration to be inlined.

  12. #12
    Registered User
    Join Date
    Nov 2004
    Posts
    69
    Quote Originally Posted by Daved
    Since both controller.cpp and main.cpp are including controller.h, the compiler compiles the functions in controller.h both times, and you get errors in the linking because they are defined multiple times. So the definitions for those functions (CControllerFunc::CControllerFunc() and CControllerFunc::~CControllerFunc()) in your header file should go in the controller.cpp file instead, or they should be moved inside the class declaration to be inlined.
    That would beat the point of the header file. I don't wanna do that.
    There another alternative?

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    That doesn't beat the point of the header file, since the class declaration would still go in the header and the class method definitions would go in the source file.

    An alternative is to make the method definitions inline. You can do that by moving the definition inside the class declaration (instead of ending the constructor declaration with a semi-colon replace that with the block of code for the method itself).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  2. Testing some code, lots of errors...
    By Sparrowhawk in forum C Programming
    Replies: 48
    Last Post: 12-15-2008, 04:09 AM
  3. Errors including <windows.h>
    By jw232 in forum Windows Programming
    Replies: 4
    Last Post: 07-29-2008, 01:29 PM
  4. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  5. Using VC Toolkit 2003
    By Noobwaker in forum Windows Programming
    Replies: 8
    Last Post: 03-13-2006, 07:33 AM