The short story:
I need to be able to cast a function pointer for any function and class to an intermediate type, so I could call it from any point of my program using the "__asm call" instruction.
The long story:
I have been trying to develop a data driven method to call C++ functions, that allows calling them with minimal overhead. The final goal is to be able to call any function, by knowing just what kind of parameters to send to it.
Now, I immediately figured out that C/C++ don't have a mechanism that allows such behavior without raising template hell, so after some research I came up with the following chunks of code:
Now, the above code has been working great and I thought I had nailed it, but while putting the whole thing together, something unexpected happened:
After some more researching on the matter, I found out that function pointers are not actual pointers, but contain additional data (for virtuality, etc...) which explains why casting to a normal pointer would not be allowed.
However, what puzzles me the most is how call mem_ptr is allowed on a non-pointer. The call instruction should only work on a memory address, right?
I looked at the disassembly, but there were no signs of the code being expanded any further (other than a jmp right after the call, which the compiler probably kept for vtable handling).
I tried going over the C++ specification but to no avail. Google couldn't help me either.
So my question is this: how do I convert mem_ptr to an arbitrary data type, that can later be called without the actual function prototype (just abstract pointers to the func and class, and knowledge of the parameter).
The idea behind all this is to allow me to assign a unique identifiers during compilation, which I would then use to translate into pointers during runtime and be able to repeatedly call the said functions with minimal overhead.
I realize the implications of throwing away C++'s type safety out of the window, but the benefits far out weight the risks in my situation.
Any thoughts on this would be greatly appreciated.
I need to be able to cast a function pointer for any function and class to an intermediate type, so I could call it from any point of my program using the "__asm call" instruction.
The long story:
I have been trying to develop a data driven method to call C++ functions, that allows calling them with minimal overhead. The final goal is to be able to call any function, by knowing just what kind of parameters to send to it.
Now, I immediately figured out that C/C++ don't have a mechanism that allows such behavior without raising template hell, so after some research I came up with the following chunks of code:
Code:
// Call a non-member/static function:
void(*func_ptr)(int, int) = &myFunc;
__asm {
push b ; // 2nd parameter
push a ; // 1st parameter
call func_ptr
add esp, 8 ; // more accurately it's sizeof(int)*2
}
Code:
// Call a memer function:
myClass ob;
void(myClass::*mem_ptr)(int, int) = &myClass::myMemFuc;
__asm {
push b ; // 2nd parameter
push a ; // 1st parameter
lea ecx, [ob]
call mem_ptr
; no need to unwind the stack for some reason that is beyond me
}
Now, the above code has been working great and I thought I had nailed it, but while putting the whole thing together, something unexpected happened:
Code:
void* pFunc = func_ptr; // ok, works great with call void* pMem = mem_ptr; // compiler error 2440 in Visual Studio
However, what puzzles me the most is how call mem_ptr is allowed on a non-pointer. The call instruction should only work on a memory address, right?
I looked at the disassembly, but there were no signs of the code being expanded any further (other than a jmp right after the call, which the compiler probably kept for vtable handling).
I tried going over the C++ specification but to no avail. Google couldn't help me either.
So my question is this: how do I convert mem_ptr to an arbitrary data type, that can later be called without the actual function prototype (just abstract pointers to the func and class, and knowledge of the parameter).
The idea behind all this is to allow me to assign a unique identifiers during compilation, which I would then use to translate into pointers during runtime and be able to repeatedly call the said functions with minimal overhead.
I realize the implications of throwing away C++'s type safety out of the window, but the benefits far out weight the risks in my situation.
Any thoughts on this would be greatly appreciated.
Comment