C++ problem

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
ipsp
Posts: 26
Joined: Wed Feb 01, 2006 9:46 am
Location: Sydney

C++ problem

Post by ipsp »

I'm trying to write some C++ library classes, so i can reuse them for all of my projects, and having some trouble. For some reason it refuses to link, and i cannot see what it is.

Here is source, and error, can anyone help.

main.cpp

Code: Select all

#include <pspkernel.h>
#include <pspdebug.h> 

#include "PspExitHandler.h"

PSP_MODULE_INFO&#40;"testClass_cpp", 0, 1, 1&#41;; 

int main&#40;&#41; 
&#123;
    pspDebugScreenInit&#40;&#41;;
    PspExitHandler&#58;&#58;SetupCallbacks&#40;&#41;;
        	
    pspDebugScreenPrintf&#40;"Hello World"&#41;; 
    sceKernelSleepThread&#40;&#41;; 
    return&#40;0&#41;; 
&#125; 
PspExitHandler.cpp

Code: Select all

#include <pspkernel.h>
#include <pspdebug.h> 

class PspExitHandler 
&#123; 
    public&#58;
           
        static int SetupCallbacks&#40;void&#41;
	    &#123;
            int thid = sceKernelCreateThread&#40;"update_thread", PspExitHandler&#58;&#58;callbackThread, 0x11, 0xFA0, 0, 0&#41;;

            if &#40;thid >= 0&#41; sceKernelStartThread&#40;thid, 0, 0&#41;; 
            return&#40;0&#41;;       
        &#125;
	
    private&#58;
           
	    static int exit_callback&#40;int arg1, int arg2, void * common&#41;
       &#123;
            sceKernelExitGame&#40;&#41;;
            return&#40;0&#41;;
       &#125;
    
	    static int callbackThread&#40;SceSize args, void *argp&#41;
	    &#123;
            int cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;;
            sceKernelRegisterExitCallback&#40;cbid&#41;;

            sceKernelSleepThreadCB&#40;&#41;;
            return&#40;0&#41;;               
       &#125;
&#125;;
PspExitHandler.h

Code: Select all

class PspExitHandler 
&#123; 
    public&#58;

        static int SetupCallbacks&#40;void&#41;;

    private&#58;
  
        static int exit_callback&#40;int arg1, int arg2, void * common&#41;;
	    static int callbackThread&#40;SceSize args, void *argp&#41;;
&#125;; 
makefile

Code: Select all

TARGET = testClass
OBJS = main.o PspExitHandler.o

CFLAGS = -O2 -G0 -Wall 
CXXFLAGS = $&#40;CFLAGS&#41; -fno-exceptions -fno-rtti
ASFLAGS = $&#40;CFLAGS&#41;


LIBDIR = 
LDFLAGS = 
LIBS = -lstdc++ -lpng -lz -lm -lpspgu 

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Test Class

PSPSDK=$&#40;shell psp-config --pspsdk-path&#41;
include $&#40;PSPSDK&#41;/lib/build.mak 
Compile output

Code: Select all

psp-g++ -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall  -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall  -fno-exceptions -fno-rtti   -c -o main.o main.cpp
psp-g++ -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall  -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall  -fno-exceptions -fno-rtti   -c -o PspExitHandler.o PspExitHandler.cpp
psp-gcc -I. -I/usr/local/pspdev/psp/sdk/include -O2 -G0 -Wall   -L. -L/usr/local/pspdev/psp/sdk/lib   main.o PspExitHandler.o -lstdc++ -lpng -lz -lm -lpspgu  -lpspdebug -lpspdisplay -lpspge -lpspctrl -lpspsdk -lc -lpspnet -lpspnet_inet -lpspnet_apctl -lpspnet_resolver -lpsputility -lpspuser -lpspkernel -o testClass.elf

main.o In function `main'&#58;
main.cpp&#40;.text+0x10&#41;&#58; undefined reference to `PspExitHandler&#58;&#58;SetupCallbacks&#40;&#41;'

collect2&#58; ld returned 2 exit status
make&#58; *** &#91;testClass.elf&#93; Error 1
Dr. Vegetable
Posts: 171
Joined: Mon Nov 14, 2005 1:32 am
Location: Boston, Massachusetts
Contact:

Post by Dr. Vegetable »

I don't see any obvious syntactical probems with your code. However, I am able to get it to link if I modify your PspExitHandler.cpp file to look like this:

Code: Select all

#include <pspkernel.h> 
#include <pspdebug.h> 
#include <PspExitHandler.h>

//static
int PspExitHandler&#58;&#58;SetupCallbacks&#40;void&#41; 
&#123; 
    int thid = sceKernelCreateThread&#40;"update_thread", PspExitHandler&#58;&#58;callbackThread, 0x11, 0xFA0, 0, 0&#41;; 

    if &#40;thid >= 0&#41; sceKernelStartThread&#40;thid, 0, 0&#41;; 
        return&#40;0&#41;;        
&#125; 
    
//static
int PspExitHandler&#58;&#58;exit_callback&#40;int arg1, int arg2, void * common&#41; 
&#123; 
    sceKernelExitGame&#40;&#41;; 
    return&#40;0&#41;; 
&#125; 
    
//static
int PspExitHandler&#58;&#58;callbackThread&#40;SceSize args, void *argp&#41; 
&#123; 
    int cbid = sceKernelCreateCallback&#40;"Exit Callback", exit_callback, NULL&#41;; 
    sceKernelRegisterExitCallback&#40;cbid&#41;; 

    sceKernelSleepThreadCB&#40;&#41;; 
    return&#40;0&#41;;                
&#125; 
Note that this code is identical to yours, except that I have moved the static function definitions "out-of-line."

As a matter of style, I usually try to avoid having more than one copy of a class declaration, and it is possible that the compiler is somehow deciding that these are two different physical classes. By using the same .h file both for references to your class and for the definition of your class, you avoid potential problems keeping the two files in sync.

Hope this helps!
ipsp
Posts: 26
Joined: Wed Feb 01, 2006 9:46 am
Location: Sydney

Post by ipsp »

Dr. Vegetable wrote:
As a matter of style, I usually try to avoid having more than one copy of a class declaration, and it is possible that the compiler is somehow deciding that these are two different physical classes. By using the same .h file both for references to your class and for the definition of your class, you avoid potential problems keeping the two files in sync.

Hope this helps!
What you said makes perfect sense and helps alot, I'm personally having trouble adjusting from Java and C, to C++ but that helped heaps.

Thanks
seventh
Posts: 11
Joined: Sat Jan 21, 2006 2:10 am

Post by seventh »

The problem is, your .cpp file does not only provide implementation, it also provides interface. In theory, you should have

MyClass.h

Code: Select all

class MyClass &#123;

 public &#58; static void my_function&#40; void &#41;;
&#125;;
MyClass.cpp

Code: Select all

#include "MyClass.h"

void MyClass&#58;&#58;my_function&#40; void &#41; &#123; /* ... */ &#125;
It is just that you don't use C++ the good way, nothing to do with specific PSP programming
Post Reply