tags:

views:

256

answers:

10

Hello, 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 http://stackoverflow.com/questions/2025228/creating-function-pointers-to-functions-created-at-runtime/2025313#2025313

A: 

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

Shmoopty
I want to do that to a big number of functions at max 0xFFFF
+1  A: 

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);
        }

}
Mark Wilkins
Forgot an array index in there I think: (*funcs[i])(i);
Drew Hall
Yes indeed. Thanks for pointing that out; I just now fixed it. The funny thing is that I actually compiled and ran it ... and I saw what I wanted to see rather than what was actually printed.
Mark Wilkins
A: 

I haven't made myself clear. I use a for from 0 to 9 but the point in functions at runtime is that I can have up to 0xFFFF functions.

Edit your question to include the new information or make a comment on your question. New information for a question doesn't belong in the answer section, only answers do.
Omnifarious
+1  A: 

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.

sth
A: 

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).

tamulj
A: 

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 someFunctionUnknownAtCompileTime() 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.

Please edit your question rather than adding your own answers to clarify the question.
Drew Hall
A: 

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();
Igor Zevaka
Thanks but it has nothing to do with that.
+2  A: 

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.

Drew Hall
I think you didn't understood me correctly. What I want to do is to patch with an assembly jump several functions unknown at compile time. (Detour them). And each jump should be to a function related to a different number. EDIT: reading again your post you did understood more than I thought. The question is: how to generate that machine code?
Wait, I think I got you. I will try to fill memory with groups of assembly instructions representing functions and provide the adresses of them.
@unknown: Be careful--what you want is not assembly, but machine code (that is, the output of an assembler, binary machine code).
Drew Hall
My comment regarding pointers to member functions still stands though. You will need two bits of information - the address of the object and the address of the function (since objects in C++ are simply a block of memory containing its members).
Igor Zevaka
Igor, i'm aware of that and that's is not the issue. Drew, yes I misnamed it. Anyway it's solved and tested and it works and thanks.
A: 

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 :)

hype
I was hoping that lambda functions provided by some library give me a solution. Yes you understood correctly.
A: 

Solved thanks to Drew Hall.

Solution: produce the functions in assembly and put them in an array and do the jumps to the address of each function taking into account their position in the array.