simple function calling not working

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
earlz

simple function calling not working

Post by earlz »

I am making a test function for my gui but my very simple event handler caller does not work, it causes a triple fault
this is the condensed code

Code: Select all

typedef struct{
   video_info draw_inf; //tells video info for window
     void *func_ptrs[256]; //data ptr for event interrupts
     void *draw_buffer; //this is where the drawing buffer is
     void *owner;
     char *title; //this is the shown title
     unsigned int x,y; //where on the screen the window is
     // the drawing buffer has all the characters/pixels for the window and is updated to its parent window which is eventually
     // updated to the video memory
   unsigned int attributes; //attributes for everything
   unsigned int rnumber; //what the registered number is, populated by RegisterWindow
     
}WINDOW;

WINDOW mcon;
void init(){
     mcon.func_ptrs[7]=&gotkey;
}

void test_func(){
call_evh(mcon,7,0);
}
typedef void(*EvhFunc)(unsigned char,unsigned int);
void call_evh(WINDOW win,unsigned char event,unsigned int parameter){ //this is the problem i think
     EvhFunc tmp;
     tmp=win.func_ptrs[event];
     tmp(event,parameter);
}



xenos

Re:simple function calling not working

Post by xenos »

Have you checked whether your function pointer really points to the function you would like to call? Maybe it contains a wrong address, causing a GPF (and possibly a triple fault if you don't catch it).
earlz

Re:simple function calling not working

Post by earlz »

Code: Select all

    mcon.func_ptrs[7]=&gotkey;
gotkey is a function of void gotkey(unsigned char,unsigned int)
how would the poitner not actually point to it?
Cjmovie

Re:simple function calling not working

Post by Cjmovie »

It's been a long time....And right now I'm tired....but I'll attempt to help out.

Code: Select all

mcon.func_ptrs[7]=&gotkey;
Will create a pointer to a pointer to the function. Instad you would want:

Code: Select all

mcon.func_ptrs[7]=(void*)gotkey;
Note the cast. When you call it, you'll also need to cast it back. If you didn't want to deal with casting, you'd have to define the function pointer list like this:

Code: Select all

void (*func_ptrs)(unsigned char, unsigned int)[256]; //data ptr for event interrupts
At the same time, however, I think gcc does not allow an array of function pointers. So the code would really be:

Code: Select all

//Structure Implementation
typedef struct{
 ...
 void *func_ptrs[256];
 ...
}

//To set a function in the array
func_ptrs[0] = (void*)gotKey;

//To call the function
void (*Function)(unsigned char, unsigned int);
Function = func_ptrs[0];
Function('a', 5);

earlz

Re:simple function calling not working

Post by earlz »

I tried what you said but i still get a triplefault
paulbarker

Re:simple function calling not working

Post by paulbarker »

Can you tell us which fault it's producing? Bochs should tell you in the log file even if it goes on to triple fault.

Also, why are you passing a WINDOW object around rather than a pointer to one?
nick8325
Member
Member
Posts: 200
Joined: Wed Oct 18, 2006 5:49 am

Re:simple function calling not working

Post by nick8325 »

Have you tried changing the func_ptrs declaration to EvhFunc func_ptrs[256], and removing all the casts? That way the compiler should be able to catch type errors properly...

(p.s. a void * is not guaranteed to be able to hold a function pointer)
earlz

Re:simple function calling not working

Post by earlz »

00074284785e[CPU0 ] exception(): 3rd (14) exception with no resolution, shutdown status is 00h, resetting
is that it? i dont see anything else

and yes i did do the EvhFunc type cast on it
paulbarker

Re:simple function calling not working

Post by paulbarker »

The 14 is the exception number which would be..... Page fault?

I'm pretty confident you're mangling the table somewhere. Could you post the code that calls test_func and init?

Btw you're passing a structure of at least 1k size on the stack. You could be overflowing the stack with the call to call_evh. Use a pointer!
earlz

Re:simple function calling not working

Post by earlz »

oh ok so thats why people always use ptr's

yes it must have been stack overflow cause changing it to a ptr made it work
thanks everyone
proxy

Re:simple function calling not working

Post by proxy »

sorry to jump in without actually offering any help but I had to make a correction to something i read here written by Cjmovie:
At the same time, however, I think gcc does not allow an array of function pointers. So the code would really be:
I call B.S. on that one, big time. you may have an array of any type and this includes functions pointers. The easiest way to do it would be with a typedef like this:

Code: Select all

typedef void (*func_ptr)(int); /* defines type for pointer to function taking an int param and returning void */

func_ptr f[100]; /* array of 100 function pointers */
also, note that it is not neccessary to use the unary-address of operator '&' to get the address of a function (though it is not an error to do so, it's just unneccerssary), the name of a function itself is considered a function pointer just fine. However, in both C and C++ &func will equal func, so the following is also valid:

Code: Select all

void my_func(int param) {
/* do stuff */
}

f[0] = my_func;
f[1] = &my_func;

/* f[0] and f[1] will have the same value */
similarly it is equally uneccessary to dereference a function pointer but technically not an error, personally i prefer to do so, so that it is clear in code it is a function pointer like this:

Code: Select all

(*f[0])(param);
/* or */
f[0](param);
The following code demonstrates this to be true:

Code: Select all

(00:13:12) LaptopProxy: 
#include <stdio.h>

typedef void (*func_ptr)(int);

void my_func(int param) {
   printf("hello\n");
}

int main() {
   func_ptr f[100];
   f[0] = &my_func;
   f[1] = my_func;
   
   printf("%p:%p\n", f[0], f[1]);
   
   f[0](0);
   (*f[0])(0);
   
   return 0;
}

the output would look something like this:

Code: Select all

0x8048394:0x8048394
hello
hello
Post Reply