Just need to get a frikkin function ptr!(C)

Programming, for all ages and all languages.
Post Reply
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Just need to get a frikkin function ptr!(C)

Post by earlz »

FIXED: LOOK AT BOTTOM
I know this is probably something obvious but it is not working so..

I am using gcc
I can not figure out to get a function ptr, without the function being in the same source file

this is my code:(not compiling)

Code: Select all

inline void InstallOp(unsigned char num,void *func){
     Opcodes[num]=func;
}

void UninstallOp(unsigned char num){ //actually just sets the opcode to unknown
     Opcodes[num]=unknown();
}
//void unknown();
void InitOpcodes(){

     unsigned int i;
          Opcodes=malloc(0xFF*sizeof(void *)); //trying to get ready for 64bit...lol
          for(i=0;i<=0xFF;i++){
              //HERE IS ERROR #1
               InstallOp(i,unknown); //set all opcodes to unknown..
          }
          //HERE IS ERROR #2
          InstallOp(0xF4,&hlt());

}
hlt and unknown are simple void func(); type functions
in error #1 it says that unknown is undefined even though if I try to define it as extern or a function it will throw an error of conflicting types

in error #2
I try getting the address of the function by a non-standard way(works on some compilers) but in gcc it treats it like trying to & a void (blank datatype..) and if I try removing the & then it trys running the function hlt() so that it can get the return value

so exactly how do I get the ptr to a function!?(without using some ridicoulous thing like using asm offset or just putting all my functions together in 1 source file)


EDIT:
ok dunno why but gcc doesn't like for function declarations to be done in source files, everything works if I put "void unknown();" in my global header file... very wierd problem
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Post by gaf »

Hi hckr83,
In my opinion you should have a look at some tutorials about C function-pointers. Your current approach circumvents the actual problem as you cast the pointer to store it in an array. This might work for the moment but it will cause some issues once you try to actually call your opcode handlers. Eventually you'll be forced to use some assembler hack if you don't store the handlers as C style function-pointers.
In error #1 it says that unknown is undefined even though if I try to define it as extern or a function it will throw an error of conflicting types
That's because function-pointers and data-pointers aren't the same in a high-level language. You could cast the fucntion to a void-pointer, but that would mean losing the ability to call the procedure. A better approach is thus to simply store the function addresses in an array of C function pointers.
I try getting the address of the function by a non-standard way(works on some compilers) but in gcc it treats it like trying to & a void (blank datatype..) and if I try removing the & then it trys running the function hlt() so that it can get the return value
Any compiler that accepts your code ignores the C standard. The correct way is to either use "InstallOp(0xF4, halt)" or the more obvious "InstallOp(0xF4, &function)". In both cases brakets aren't used as no function gets called.

Code: Select all

extern void unknown(); // Defined in some other source-file
extern void hlt();

typedef void (*function)();  // function is a datatype
function Opcodes[LIMIT];   // Array of function-pointers

void InstallOp(unsigned char num, function func)
{ 
     Opcodes[num] = func; 
} 

void UninstallOp(unsigned char num)
{
     Opcodes[num] = &unknown; 
}

void HandleOpcode(unsigned char num)
{
     function opcode = Opcodes[num];
     return opcode(); // Call the procedure, (*opcode)() is also valid
}

void InitOpcodes()
{ 
     unsigned int i; 
     Opcodes=malloc(0xFF*sizeof(function)); 
     
     for(i=0;i<=0xFF;i++)
     { 
         InstallOp(i, &unknown);
     } 
     InstallOp(0xF4, &hlt); 
}
regards,
gaf
earlz
Member
Member
Posts: 1546
Joined: Thu Jul 07, 2005 11:00 pm
Contact:

Post by earlz »

I knew how function ptr's worked, they were working fine and thought it was irrelevent to this post really though(I like how C would let you do func_ptr[26](); )
User avatar
gaf
Member
Member
Posts: 349
Joined: Thu Oct 21, 2004 11:00 pm
Location: Munich, Germany

Post by gaf »

I knew how function ptr's worked, they were working fine and thought it was irrelevent to this post
Actually it's the most relevent part of your whole post as the first error gets a compeltly different meaning without it. Due to that ambiguity I thought that you're trying to convert your function-pointer to a void-pointer. As this had however required an explizit C cast, your compiler would've complained about just that line.

Provided that you're using function-pointers there's probably a completly different conversion problem. Most likely your hlt() definition didn't match the function-pointer type required by the InstallOp() procedure. This means that hlt() differs in return-value and/or number and type of arguments from the definition of the function-pointer

Code: Select all

extern void FunctionA(void);
extern long FunctionB(void);
extern void FunctionC(long);

void (*function) (void);

function = &FunctionA;  // OK
function = &FunctionB;  // Different return values
function = &FunctionC;  // Wrong parameter(s)
GCC doesn't like for function declarations to be done in source files, everything works if I put "void unknown();" in my global header file.
That really can't be the reason as "Include <something>" just means "paste the content of something here". This is already done by the preprocessor, so that the compiler itself won't see any difference at all.

regards,
gaf
Post Reply