Thread: Function Pointer?

  1. #1
    Registered User
    Join Date
    Dec 2002
    Posts
    162

    Question Function Pointer?

    Hi all,

    Is it possible to declare a function pointer outside function arguments? I mean like declaring a pointer as a separate variable which isn’t an argument and can change the function it is pointing at, assuming that whatever function it points at always has the same arguments. Like this code for example. Please note that I know this following code doesn’t compile, I just want to explain my question in code, it’s always a lot easier.

    Code:
    void realfunc(void){ // declaring a normal function with no arguments
          return;
    }
    
    int main(){
          void (*funcptr)(void); // declaring “function pointer” with no arguments
          *funcptr=realfunc; // “function pointer” pointing at a normal function with same argument settings
          funcptr(); // calling the function that the “function pointer” is pointing at
          return 0;
    }
    So is there something similar to this code? In other words is it possible to do something like this?
    Last edited by Aidman; 01-06-2003 at 04:18 PM.
    We haven't inherited Earth from our parents; instead we have borrowed her from our children - old Indian saying.

  2. #2
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    It should compile if you change it to be:

    Code:
    void realfunc(void){
          return;
    }
    
    int main(){
          void (*funcptr)(void) = realfunc;
          funcptr=realfunc; // or like this
          funcptr();
          (*funcptr)(); // or like this
          return 0;
    }
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

  3. #3
    Registered User
    Join Date
    Dec 2002
    Posts
    162

    Question Advanced Function Pointer?

    Great, Thank you " IfYouSaySo"!
    I am sorry I feel a little dumb, not realizing that C++ must hade such a method.

    But here’s another “function pointer” related question, which may be more advanced, if that’s ok? Let’s say you have a function (in your own application) whose arguments are cstomable stored in variable arrays and the function name you don’t know. The only thing you have as a pointer of the function is a simple memory pointer/adress (no real function pointer) that points to a memory location where the function is stored during run-time. The following code example would demonstrate what I am trying to say.

    Code:
    // MEMPTR is a variable type pointing to a location in memory
    
    struct FUNCSTRUCT { // Function calling structure
          MEMPTR *FunctPtr; // Function pointer
          int VarCount; // Number of Variables
          MEMPTR *VarPtr[255]; // Varaible pointers
          int VarSize[255]; // Varaible byte sizes
    }
    
    MEMPTR CallFunc(FUNCSTRUCT *FunctData); // The powerful function that does the call
    
    int TheRealFunc(int Argument){ // Declare normal function
          return Argument;
    }
    
    int main(){
          FUNCSTRUCT FuncData; // Declare function type
          int Value = 1; // Give a value to send as argument
    
          FuncData.FunctPtr = TheRealFunc; // Point to normal function
          FuncData.VarCount = 1; // Number of values to send as arguments
          FuncData.VarPtr[0] = Value; // Point to the value
          FuncData.VarSize[0] = 2; // Byte size of an integer value
    
          return CallFunc(&FuncData); // Call the function
    }
    Is it possible to create such a function as “CallFunc” that could call a function, only knowing the custom arguments and a memory pointer/address? If so then how and how would the “MEMPTR” variable type look like? I presume that this question is a lot harder and I guess it includes some low-level knowledge. But is this possible and if it is then please explain how and demonstrate it in code please or could you point me to a tutorial on this
    Last edited by Aidman; 01-06-2003 at 06:08 PM.
    We haven't inherited Earth from our parents; instead we have borrowed her from our children - old Indian saying.

  4. #4
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Don't know if this will help, but I posted a function pointer snippet here

    Ask again if it doesn't help. There are various ways to do things, so don't worry if you don't like my example code
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  5. #5
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    Personally, I would use a function object. Basically you create a class, and pass the constructor the arguments for the function call. You store those arguments as class member data. Then you overload the function call operator, and the class can be called as if it was a function. You could make an array if you wanted to.... Hopefully this compiles, I just sort of typed it in here over a beer. Let me know if it doesn't quite work.

    Example:

    Code:
    #include <iostream>
    using namespace std;
    
    class FunctionObject {
    public:
    int data1;
    char data2;
    double data3;
    
    FunctionObject(int one, char two, double three) 
    {
       data1 = one;
       data2 = two;
       data3 = three;
    }
    
    void operator()() 
    {
        cout<<"Inside operator(), data1 is "<<data1
               <<" data2 is "<<data2
               <<" data3 is "<<data3<<endl;
    }
    
    };
    
    int main()
    {
        FunctionObject fObj(25,'c',3435.234);
    
        fObj();
        
        return 0;
    }
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

  6. #6
    Registered User
    Join Date
    Dec 2002
    Posts
    162

    Question

    Do you have any ideas of where I might find some info on how to call and get function pointers like in my code?
    We haven't inherited Earth from our parents; instead we have borrowed her from our children - old Indian saying.

  7. #7
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    Your original code had only one small error, which was corrected by IfYouSaySo (2nd post on this thread). Do you have further questions?
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  8. #8
    Registered User
    Join Date
    Dec 2002
    Posts
    162

    yes

    Yes I am refering to my question in post 3.

    The code in post 5 from "IfYouSaySo" is argumetns constant, meaning the functions you call with that class must have same argument settings. I want to know how to call a function which you onlyhave a pointer for and editable variable arguments to send. So the user can choose which function pointer to call and setup the argument arrays to match the calling function. Like a function that can call a API dll function but only knowing its name and library name, and the arguments are passed as arrays like in my "FUNCSTRUCT" above.
    Last edited by Aidman; 01-07-2003 at 08:54 AM.
    We haven't inherited Earth from our parents; instead we have borrowed her from our children - old Indian saying.

  9. #9
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    You can achieve variable/different arguments with function objects by using polymorphism:

    -Make a base class with virtual operator(). I'm kinda sketchy on this fact, because I'm not sure it operator() can actually be virtual. Maybe somebody else knows. If not you can make some other function name, like Call(), DoIt(), or whatever that each derived class implements.
    -derived classes can have multiple data members of different type (parameters) that implement the above function.
    -Make an array of base class pointers pointing to dynamically allocated derived types. (polymorphism).
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

  10. #10
    Registered User
    Join Date
    Dec 2002
    Posts
    162

    re: polymorphism

    thanks for the idea.

    But I don't know anything about "polymorphism" or what how to use "derived class implements". Could you please demonstrate or explain this in code or point me to a good tutorial/articel on this?
    We haven't inherited Earth from our parents; instead we have borrowed her from our children - old Indian saying.

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    There would be no easy way to do that with variable arguments. I'm not saying it can't be done but it would be complicated, and quite possibly an ugly hack. Your best bet would be a function in your base class that used the function name (not a pointer) and the va_list macros, from there it could "lookup" the function by calling a virtual function or similar in a child class. The va_list function could pack the arguments into an array of chars, a buffer, and could call the lookup like:

    Code:
    class Base {
     public:
    int Execute(const char * function, ...){
    //...va_list stuff...
    //...count each arg and also calc arg_buff_length
    //...store each variable into arg_buff...
    return FindCall(function, num_args, arg_buff, arg_buff_length);
    }
    virtual int FindCall(const char * function, int arg_count, char * arg_buff, int arg_buff_length) = 0;
    };
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  12. #12
    Registered User
    Join Date
    Dec 2002
    Posts
    162
    Could you use this method for API calls too?
    We haven't inherited Earth from our parents; instead we have borrowed her from our children - old Indian saying.

  13. #13
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Wouldn't something like this work?

    Code:
    template<class A, class B, class C, class D>
    class FunctStruct
    {
    public:
      void operator=(A (*ptr)(B,C,D))
      {
         fptr = ptr;
      }
       A operator()(B b,C c, D d)
       {
          return fptr(b,c,d);
       }
    private:
      A (*fptr)(B,C,D);
    };
    
    ////Code could look like this:
    
    int myfunc(char, long, int);
    
    int main()
    {
      FunctStruct<int,char,long,int> f;
      f = myFunc;
      f('d',23,1);
    }
    I haven't compiled this, but something like this should work, although one class for each number of argument would have to be created.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  14. #14
    Registered User
    Join Date
    Aug 2002
    Location
    Hermosa Beach, CA
    Posts
    446
    Okay here is what I would do:

    Code:
    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    class FunctBase {
    public:
       virtual void operator()() = 0;
    };
    
    class FunctDerived : public FunctBase {
       private:
       // these are what you would normally associate as
       // function parameters, but you only pass them into
       // the constructor of this class
       int data1;
       bool data2; 
       public:
       FunctDerived( int i, bool b ) { data1 = i; data2 = b; }
       void operator()() 
       {
            // do whatever you want here:
    	    cout<<"Executing FunctDerived"<<endl;
            cout<<"Data1: "<<data1<<endl;
            cout<<"Data2: "<<data2<<endl;
       }
        
    };
    
    class AnotherDerived : public FunctBase {
       // different parameter list
       void* v;
       string s;
       public:
       AnotherDerived(void* _v, string& _s) { v = _v; s = _s; }
       void operator()()
       {
    	    cout<<"Executing AnotherDerived"<<endl;
    		cout<<"Void* is : "<<v<<endl;
    		cout<<"String is: "<<s.c_str()<<endl;
       }
    };
    
    class DoCall {
    public: 
       void operator()(FunctBase* fb) 
       {
           (*fb)();
       }
    };
    
    
    int main()
    {
        vector<FunctBase*> ptrs;
    
        ptrs.push_back(new FunctDerived(254,true));
        ptrs.push_back(new AnotherDerived(NULL,string("Some String")));
    
        for_each( ptrs.begin(), ptrs.end(), DoCall() );
    
    	// cleanup code omitted
    
        return 0;
    }
    The crows maintain that a single crow could destroy the heavens. Doubtless this is so. But it proves nothing against the heavens, for the heavens signify simply: the impossibility of crows.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  3. Function Pointer help
    By Skydt in forum C Programming
    Replies: 5
    Last Post: 12-02-2005, 09:13 AM
  4. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM