开发者

Creating function pointers to functions created at runtime

I would like to do something like:

for(int i=0;i<10;i++)
    addresses[i] = & function(){ callSomeFunction(i) };

Basically, having an array of addresses of functions with behaviours related to a list of numbers.

If it's possible with external classes like Boost.Lambda is ok.

Edit: after some discussion I've come to conclusion that I wasn't explicit enough. Please read Creating function pointers to functions created at runtime


What I really really want to do in the end is:

class X
{
    void action();
}

X* objects;

for(int i=0;i<0xFFFF;i++)
    addresses[i] = & function(){ objects[i]->action() };


void someFunctionUnknownAtCompileTime()
{

}

void anotherFunctionUnknowAtCompileTime()
{

}

patch someFunctionUnkno开发者_JS百科wnAtCompileTime() with assembly to jump to function at addresses[0]

patch anotherFunctionUnknownAtCompileTime() with assembly to jump to function at addresses[1]

sth, I don't think your method will work because of them not being real functions but my bad in not explaining exactly what I want to do.


If I understand you correctly, you're trying to fill a buffer with machine code generated at runtime and get a function pointer to that code so that you can call it.

It is possible, but challenging. You can use reinterpret_cast<> to turn a data pointer into a function pointer, but you'll need to make sure that the memory you allocated for your buffer is flagged as executable by the operating system. That will involve a system call (LocalAlloc() on Windows iirc, can't remember on Unix) rather than a "plain vanilla" malloc/new call.

Assuming you've got an executable block of memory, you'll have to make sure that your machine code respects the calling convention indicated by the function pointer you create. That means pushing/popping the appropriate registers at the beginning of the function, etc.

But, once you've done that, you should be able to use your function pointer just like any other function.

It might be worth looking at an open source JVM (or Mono) to see how they do it. This is the essence of JIT compilation.


Here is an example I just hacked together:

int func1( int op )
{
   printf( "func1 %d\n", op );
   return 0;
}
int func2( int op )
{
   printf( "func2 %d\n", op );
   return 0;
}

typedef int (*fp)(int);


int main( int argc, char* argv[] )
{
    fp funcs[2] = { func1, func2 };
    int i;

    for ( i = 0; i < 2; i++ )
        {
        (*funcs[i])(i);
        }

}


The easiest way should be to create a bunch of boost::function objects:

#include <boost/bind.hpp>
#include <boost/function.hpp>
// ...

std::vector< boost::function<void ()> > functors;
for (int i=0; i<10; i++)
   functors.push_back(boost::bind(callSomeFunction, i));

// call one of them:
functors[3]();

Note that the elements of the vector are not "real functions" but objects with an overloaded operator(). Usually this shouldn't be a disadvantage and actually be easier to handle than real function pointers.


You can do that simply by defining those functions by some arbitrary names in the global scope beforehand.


This is basically what is said above but modifying your code would look something like this:

std::vector<int (*) (int)> addresses;
for(int i=0;i<10;i++) {
     addresses[i] = &myFunction;  
}

I'm not horribly clear by what you mean when you say functions created at run time... I don't think you can create a function at run time, but you can assign what function pointers are put into your array/vector at run time. Keep in mind using this method all of your functions need to have the same signature (same return type and parameters).


You can't invoke a member function by itself without the this pointer. All instances of a class have the function stored in one location in memory. When you call p->Function() the value of p is stored somewhere (can't remember if its a register or stack) and that value is used as base offset to calculate locations of the member variables.

So this means you have to store the function pointer and the pointer to the object if you want to invoke a function on it. The general form for this would be something like this:

class MyClass {
  void DoStuf();
};

//on the left hand side is a declaration of a member function in the class MyClass taking no parameters and returning void.
//on the right hand side we initialize the function pointer to DoStuff
void (MyClass::*pVoid)() = &MyClass::DoStuff;

MyClass* pMyClass = new MyClass();
//Here we have a pointer to MyClass and we call a function pointed to by pVoid.
pMyClass->pVoid();


As i understand the question, you are trying to create functions at runtime (just as we can do in Ruby). If that is the intention, i'm afraid that it is not possible in compiled languages like C++. Note: If my understanding of question is not correct, please do not downvote :)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜