I am coding a Gameboy Emulator, and for the CPU's instructions I use this struct here (in cpp.hpp) to store info about them. The map is used to access all this information through a key equal to its personal opcode:
struct instruction {
std::string name; //name of the instruction
int cycles; //clock cycles required to be executed
int paramNum; //number of params accepted
void* function; //code to be executed
};
class Cpu {
private:
std::map<unsigned char, instruction> instrMap;
void Cpu::fillInstructions(void);
instruction addInstruction(std::string, int, int, void*);
public:
void add_A_n(unsigned char);
}
Then in the cpu.cpp I have for example one of the function I want to cast to a function pointer in order to be assigned to the field of the struct instruction. So I have this code:
void Cpu::add_A_n(unsigned char n) {
//body
}
void Cpu::addInstructions(std::string name, int cycles, int paramNum, void* function) {
instruction i = {name, cycles, paramNum, function};
return i;
}
void Cpu::fillInstructions() {
instrMap[0x80] = Cpu::addInstruction("ADD A, n", 4, 0, (void*)&Cpu::add_A_n);
}
The goal is to fetch the opcode from the memory, then to use this opcode to retrieve from the map the information about the relative instruction, and finally to execute its function by using a switch case to select the right one:
((void (*)(void))instrMap[0x80].function)(); //for 0 params
((void (*)(unsigned char))instrMap[0x90].function)((unsigned char)operand); //for 1 param
My goal is to cast the all the functions, even the ones who requires some parameters, to the one in the struct.
The respective function it is correctly executed, but a warning is raised:
warning: converting from 'void (Cpu::)()' to 'void' [-Wpmf-conversions]
instrMap[0x80] = Cpu::addInstruction("ADD A, n", 4, 0, (void*)&Cpu::add_A_n);
How can I solve it and why does it occur? Thanks
&Cpu::add_A_n returns a pointer to a member function, which is very different from an ordinary function pointer, and the two can't be mixed. The weirdness around pointer to member functions is to account for the fact that non-static member functions all require a this instance in order to call the function.
In your case, if a function like add_A_n really doesn't depend on this, just make it static, or a non-member function:
class Cpu {
...
static add_A_n(unsigned char);
};
This way, it no longer needs a this to be called, and &Cpu::add_A_n becomes an ordinary function pointer.
Related
I am trying to create a program which saves the function pointer of a member function to an array. The program then takes the function pointer from that array and calls the function said pointer points to. This works as long as the member function used does not have any arguments. When I give it arguments the following error occurs in Visual Studio 2017:
Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.
My code is:
typedef uint8_t byte;
template<typename T>
class Test
{
public:
void FuncTest(byte* data)
{
cout << (T)(0.0625f) << endl;
}
};
typedef Test<float> fTest;
typedef Test<long long> lTest;
int main()
{
byte data[1024];
{
void (fTest::*ffp)(byte*) = &fTest::FuncTest;
//void (lTest::*lfp)(byte*) = &lTest::FuncTest;
printf("%p\n", ffp);
memcpy(&data[0], (int64*)&ffp, sizeof(int64));
}
{
int64 pData;
memcpy(&pData, &data[0], sizeof(int64));
void(*func_pointer)(byte*) = (void(*) (byte*))(pData);
printf("%p\n", pData);
func_pointer(nullptr);
}
}
If anyone could help, it would be greatly appreciated.
Ignoring the storage in an array your code is essentially:
void (Test::*ffp)(byte*) = &fTest::FuncTest;
void* pData = (void*)ffp;
void(*func_pointer)(byte*) = (void(*) (byte*))(pData);
func_pointer(nullptr);
The type of ffp is essentially (although not exactly due to differing calling conventions) void (fTest*, byte*) which doesn't match the type of func_pointer.
The solution to this is to use std::function with with either std::bind or lambdas to convert the function signatures. e.g.:
std::vector<std::function<void(byte*)>> functions;
fTest test;
functions.push_back([=](byte* data){ test.FuncTest(data); });
functions.front()(nullptr);
I have a specific problem I'm trying to solve, I need to find the location (in memory) of a class's method. I think I've hit a syntax constraint because a pointer to a method is handled as a member pointer Example:
class Foo {
public:
int targetFunction(int value) { return value + 5; }
};
DWORD findLocation() { // ignore the fact that DWORD might not equal pointer size.
int (Foo::*address)(int) = &(Foo::targetFunction); // member function pointer
void* typeHide = (void*)&address; // Remove type
DWORD targetAddress = *(DWORD*)typeHide; // Convert type from void* to DWORD* and dereference to DWORD
return targetAddress;
}
int (Foo::*address)(int) = can also be written as auto address =
Now, in VS2008, it says Foo::targetFunction's address is "0x000F B890" but &Foo::targetFunction is "0x000F 1762"
First, the member pointer works correctly using the member pointer operators .* and ->*. If I cast targetAddress back to a member pointer, it still works!
Second, the location can be a thunk function!
Finally, if I use VS2008's debugger to change the value of targetFunction from the member pointer's address 1762 to the VS debugger reported value B890, my code works correctly!
Is there a C++ specific way of getting the address value (B890) instead of the member pointer value (1762)?
Upon request, here is code I'm trying to make work:
BYTE overwriteStorage[300][2];
void NOP(void)
{
// hackish, but works for now.
}
void disableOlderVersions(DWORD _address, int index)
{
//...
_address = findLocation();
DWORD protectionStorage = 0;
VirtualProtect((void *)_address, 1+4, PAGE_WRITECOPY, &protectionStorage); // windows.h: Make Read/Write the location in code
{
BYTE *edit = (BYTE*)_address;
overwriteStorage[index][0] = *(edit+0); // store previous value to revert if needed
*(edit+0) = 0XE9; // JUMP (32-bit)
overwriteStorage[index][1] = *(edit+1); // store second value
signed int correctOffset = (signed int)NOP - (signed int)_address - 5; // calculate 0xE9 relative jump
*(signed int*)(edit+1) = correctOffset; // set jump target
}
VirtualProtect((void *)_address, 1+4, PAGE_EXECUTE, &protectionStorage);
}
if I replace the first line of findLocation from a member pointer to an actual function pointer it works perfectly. However, I need to read&write to several class methods as well, this method is broken by the odd member pointers.
Also, I've had some local functions not report the correct address either (recently). Is there possibly another way to find function addresses without being constrained by the compiler behaviors?
It sounds like you're trying to compress a member-function call into a single function pointer. It's not possible.
Remember:
Object x;
x.a(1);
is actually short for
a(&x /*this*/, 1 /*arg1, ... */); //approximation, leprechauns may be involved in actual implementations.
That first argument is crucial, it's going to become "this".
So you can't do something like this:
class Object {
public:
void f(int);
}
typedef void (*FNPTR)(int);
Object a;
void (Object::* memberFuncPtr)(int);
void* nerfedPtr = (void*)memberFuncPtrl
FNPTR funcPtr = static_cast<FNPTR>(nerfedPtr);
funcPtr(1);
Because you've robbed the member function of it's object context.
There is no way to call an object member function without having both the address of the function and the address of the instance.
I'm trying to get function addresses which are hidden behind structures. Unfortunately, the void* basic C++ conversion doesn't work, so I used C++ template instead.
1. Basic void* C++ conversion doesn't work with functions inside structures, why?
void * lpfunction;
lpfunction = scanf; //OK
lpfunction = MessageBoxA; //OK
I made a simple structure :
struct FOO{
void PRINT(void){printf("bla bla bla");}
void SETA(int){} //nothing you can see
void SETB(int){} //nothing you can see
int GETA(void){} //nothing you can see
int GETB(void){} //nothing you can see
};
///////////////////////////////////////////
void *lpFunction = FOO::PRINT;
And the compiling error :
error C2440: 'initializing' :
cannot convert from 'void (__thiscall FOO::*)(void)' to 'void *'
2. Is getting function member addresses impossible?
Then, I made a template function which is able to convert a function member to address. Then I will call it by assembly. It should be something like this:
template <class F,void (F::*Function)()>
void * GetFunctionAddress() {
union ADDRESS
{
void (F::*func)();
void * lpdata;
}address_data;
address_data.func = Function;
return address_data.lpdata; //Address found!!!
}
And here is the code :
int main()
{
void * address = GetFunctionAddress<FOO,&FOO::PRINT>();
FOO number;
number.PRINT(); //Template call
void * lpdata = &number;
__asm mov ecx, lpdata //Attach "number" structure address
__asm call address //Call FOO::PRINT with assembly using __thiscall
printf("Done.\n");
system("pause");
return 0;
}
But, I see it is extremely specific. It looks like LOCK - KEY, and I have to make a new template for every set of argument types.
Original (OK) :
void PRINT(); //void FOO::PRINT();
Modify a bit :
void PRINT(int); //void FOO::PRINT(int);
Immediately with old template code the compiler shows :
//void (F::*func)();
//address_data.func = Function;
error C2440: '=' : cannot convert from
'void (__thiscall FOO::*)(int)' to 'void (__thiscall FOO::*)(void)'
Why? They are only addresses.
69: address_data.func = Function;
00420328 mov dword ptr [ebp-4],offset #ILT+2940(FOO::PRINT) (00401b81)
...
EDIT3 : I know the better solution :
void(NUMBER::*address_PRINT)(void) = FOO::PRINT;
int(NUMBER::*address_GETA)(void) = FOO::GETA;
int(NUMBER::*address_GETB)(void) = FOO::GETB;
void(NUMBER::*address_SETA)(int) = FOO::SETA;
void(NUMBER::*address_SETA)(int) = FOO::SETB;
It's much better than template. And by the way I want to achieve the goal :
<special_definition> lpfunction;
lpfunction = FOO::PRINT; //OK
lpfunction = FOO::GETA; //OK
lpfunction = FOO::GETB; //OK
lpfunction = FOO::SETA; //OK
lpfunction = FOO::SETB; //OK
Is this possible?
Pointers to member functions are nothing like pointers to global functions or static member functions. There are many reasons for this, but I'm not sure how much you know about how C++ works, and so I'm not sure what reasons will make sense.
I do know that what you are trying in assembly simply won't work in the general case. It seems like you have a fundamental misunderstanding about the purpose of member functions and function pointers.
The thing is, you are doing some things that you would generally not do in C++. You don't generally build up tables of function pointers in C++ because the things you would use that sort of thing for are what virtual functions are for.
If you are determined to use this approach, I would suggest you not use C++ at all, and only use C.
To prove these pointer types are completely incompatible, here is a program for you:
#include <cstdio>
struct Foo {
int a;
int b;
int addThem() { return a + b; }
};
struct Bar {
int c;
int d;
int addThemAll() { return c + d; }
};
struct Qux : public Foo, public Bar {
int e;
int addAllTheThings() { return Foo::addThem() + Bar::addThemAll() + e; }
};
int addThemGlobal(Foo *foo)
{
return foo->a + foo->b;
}
int main()
{
int (Qux::*func)();
func = &Bar::addThemAll;
printf("sizeof(Foo::addThem) == %u\n", sizeof(&Foo::addThem));
printf("sizeof(Bar::addThemAll) == %u\n", sizeof(&Bar::addThemAll));
printf("sizeof(Qux::addAllTheThings) == %u\n", sizeof(&Qux::addAllTheThings));
printf("sizeof(func) == %u\n", sizeof(func));
printf("sizeof(addThemGlobal) == %u\n", sizeof(&addThemGlobal));
printf("sizeof(void *) == %u\n", sizeof(void *));
return 0;
}
On my system this program yields these results:
$ /tmp/a.out
sizeof(Foo::addThem) == 16
sizeof(Bar::addThemAll) == 16
sizeof(Qux::addAllTheThings) == 16
sizeof(func) == 16
sizeof(addThemGlobal) == 8
sizeof(void *) == 8
Notice how the member function pointer is 16 bytes long. It won't fit into a void *. It isn't a pointer in the normal sense. Your code and union work purely by accident.
The reason for this is that a member function pointer often needs extra data stored in it related to fixing up the object pointer it's passed in order to be correct for the function that's called. In my example, when called Bar::addThemAll on a Qux object (which is perfectly valid because of inheritance) the pointer to the Qux object needs to be adjusted to point at the Bar sub-object before the function is called. So Qux::*s to member functions must have this adjustment encoded in them. After all, saying func = &Qux::addAllTheThings is perfectly valid, and if that function were called no pointer adjustment would be necessary. So the pointer adjustment is a part of the function pointer's value.
And that's just an example. Compilers are permitted to implement member function pointers in any way they see fit (within certain constraints). Many compilers (like the GNU C++ compiler on a 64-bit platform like I was using) will implement them in a way that do not permit any member function pointer to be treated as at all equivalent to normal function pointers.
There are ways to deal with this. The swiss-army knife of dealing with member function pointers is the ::std::function template in C++11 or C++ TR1.
An example:
#include <functional>
// .... inside main
::std::function<int(Qux *)> funcob = func;
funcob can point at absolutely anything that can be called like a function and needs a Qux *. Member functions, global functions, static member functions, functors... funcob can point at it.
That example only works on a C++11 compiler though. But if your compiler is reasonably recent, but still not a C++11 compiler, this may work instead:
#include <tr1/functional>
// .... inside main
::std::tr1::function<int(Qux *)> funcob = func;
If worse comes to worse, you can use the Boost libraries, which is where this whole concept came from.
But I would rethink your design. I suspect that you will get a lot more milage out of having a well thought out inheritance hierarchy and using virtual functions than you will out of whatever it is you're doing now. With an interpreter I would have a top level abstract 'expression' class that is an abstract class for anything that can be evaluated. I would give it a virtual evaluate method. Then you can derive classes for different syntax elements like an addition expression a variable or a constant. Each of them will overload the evaluate method for their specific case. Then you can build up expression trees.
Not knowing details though, that's just a vague suggestion about your design.
Here is a clean solution. By means of a template wrap your member function into a static member function. Then you can convert it to whatever pointer you want:
template<class F, void (F::*funct)()>
struct Helper: public T {
static void static_f(F *obj) {
((*obj).*funct)();
};
};
struct T {
void f() {
}
};
int main() {
void (*ptr)(T*);
ptr = &(Helper<T,&T::f>::static_f);
}
It seems that you need to convert a pointer to a member function to a void *. I presume you want to give that pointer as a "user data" to some library function and then you will get back your pointer and want to use it on some given object.
If this is the case a reinterpret_cast<void *>(...) could be the right thing... I assume that the library receiving the pointer is not using it.
This question is similar to what I'm trying to do Calling C++ member function pointer from a struct .
However my structure contains a member function pointer that is defined in a different class then the one the structure is defined and used in. Here is some example code of how my classes, structures and function pointers are laid out.
// Alpha.h:
class Alpha{
public:
void function1(char name[], int number);
void function2(char name[], int number);
void function3(char name[], int number);
typedef void (Alpha::*My_func_ptr)(char name[], int number);
static My_func_ptr functionTable[];
};
// Alpha.cpp:
#include "Alpha.h"
Alpha::My_func_ptr Alpha::functionTable[] = {
&Alpha::function1,
&Alpha::function2,
&Alpha::function3
};
void Alpha::function1(char name[], int number)
{
//some stuff
}
void Alpha::function2(char name[], int number)
{
//some stuff
}
void Alpha::function3(char name[], int number)
{
//some stuff
}
// Beta.h:
#include "Alpha.h"
typdef struct{
char bName[10];
Alpha::My_func_ptr fptr;
}ptr_structure;
class Beta{
public:
void betafunction();
Alpha alphaobject;
ptr_structure str_array[3];
};
// Beta.cpp:
#include "Beta.h"
void betafunction()
{
str_array[0].fptr = alphaobject.functionTable[0];
str_array[1].fptr = alphaobject.functionTable[1];
str_array[2].fptr = alphaobject.functionTable[2];
(str_array[0].fptr)("name", 1); //gives error expression must have
//(pointer-to-) function type
(this->*str_array[0].fptr)("name", 1);
//error pointer-to-member selection class types are incompatible "Beta" and "Alpha"
//sample function pointer call using function table from other class,
//this syntax compiles and runs without error.
(alphaobject.*Alpha::functionTable[0]("name", 1);
}
As you can see I can call the function pointer from an array, but can't seem to figure out how to call a function pointer from inside an array of structures.
When calling a through member function pointer, you need to have an instance of the object associated with that pointer:
(alphaobject.*(str_array[0].fptr))("name", 1)
^^^^^^^^^^^
I would think:
(object.*functionTable[0])(args, ...);
(objptr->*functionTable[0])(args, ....);
IIRC, the combination of object and the .* operator is like a big unary operator. So that has lower precedence to the [0] postfix. However, it also has lower prededence than the function call postfix operator (args, ...)
Analogy:
(*foo)(); /* classic C */
Of course the * operator is not required when calling a regular function. But if you do write it, you need the parens, because *foo() means something else.
You can go to one of two solutions, depending on how readable you want the code. The unreadable version (which might even be wrong, and I won't even try to compile):
void Beta::betafunction() {
Alpha a;
(a.*(strArray[0].fptr))("name",1);
}
But I would actually try to make things a bit simpler:
void Beta::betafunction() {
Alpha a;
Alpha::My_func_ptr mptr = strArray[0].fptr;
(a.*mptr)("name",1);
}
I believe the second to be much more readable, and the compiler can optimize away mptr pretty easily, so there is no point in trying to play guru with the syntax.
I'll try to explain better what I want to do.
I read a file with function signatures, and I want to create a pointer to each function.
For example, a file that looks like this:
something.dll;int f(char* x, int y, SOMESTRUCT z)
something.dll;void g(void)
something.dll;SOMESTRUCT l(longlong w)
now, during runtime I want be able to create pointers to these functions (by loading something.dll and using GetProcAddress to these functions).
Now, GetProcAddress returns FARPROC which points to an arbitrary functions, but how can I use FARPROC to call these functions during runtime?
From what I know, I need to cast FARPROC to the correct signature, but I can't do it during runtime (or at least I don't know how).
Does anyone have any idea how to design do that?
Thanks! :-)
Function types are compile-time in C++, so it won't work, unless you can define all the types you're going to use in advance.
Its a matter of pushing the arguments to the stack (and local vars are like that) and calling the function as void (__cdecl *)(void).
With some other kinds of functions (like fastcall, or thiscall) it can be more problematic.
Update: I actually made an example, and it works on codepad:
(Also works with stdcall functions, because of stack restore after aligned stack alloc)
http://codepad.org/0cf0YFRH
#include <stdio.h>
#ifdef __GNUC__
#define NOINLINE __attribute__((noinline))
#define ALIGN(n) __attribute__((aligned(n)))
#else
#define NOINLINE __declspec(noinline)
#define ALIGN(n) __declspec(align(n))
#endif
//#define __cdecl
// Have to be declared __cdecl when its available,
// because some args may be passed in registers otherwise (optimization!)
void __cdecl test( int a, void* b ) {
printf( "a=%08X b=%08X\n", a, unsigned(b) );
}
// actual pointer type to use for function calls
typedef int (__cdecl *pfunc)( void );
// wrapper type to get around codepad's "ISO C++" ideas and gcc being too smart
union funcwrap {
volatile void* y;
volatile pfunc f;
void (__cdecl *z)(int, void*);
};
// gcc optimization workaround - can't allow it to know the value at compile time
volatile void* tmp = (void*)printf("\n");
volatile funcwrap x;
int r;
// noinline function to force the compiler to allocate stuff
// on stack just before the function call
NOINLINE
void call(void) {
// force the runtime stack pointer calculation
// (compiler can't align a function stack in compile time)
// otherwise, again, it gets optimized too hard
// the number of arguments; can be probably done with alloca()
ALIGN(32) volatile int a[2];
a[0] = 1; a[1] = 2; // set the argument values
tmp = a; // tell compiler to not optimize away the array
r = x.f(); // call the function; returned value is passed in a register
// this function can't use any other local vars, because
// compiler might mess up the order
}
int main( void ) {
// again, weird stuff to confuse compiler, so that it won't discard stuff
x.z = test; tmp=x.y; x.y=tmp;
// call the function via "test" pointer
call();
// print the return value (although it didn't have one)
printf( "r=%i\n", r );
}
Once you have a FARPROC, you can cast the FARPROC into a pointer to the appropriate function type. For example, you could say
int (*fPtr)(char*, int, SOMESTRUCT) = (int (*)(char*, int, SOMESTRUCT))GetProcAddress("f");
Or, if you want to use typedefs to make this easier:
typedef int (*FType)(char *, int, SOMESTRUCT);
FType fPtr = (FType)GetProcAddress("f");
Now that you have the function pointer stored in a function pointer of the appropriate type, you can call f by writing
fPtr("My string!", 137, someStructInstance);
Hope this helps!
The compiler needs to know the exact function signature in order to create the proper setup and teardown for the call. There's no easy way to fake it - every signature you read from the file will need a corresponding compile-time signature to match against.
You might be able to do what you want with intimate knowledge of your compiler and some assembler, but I'd recommend against it.