But you have to write too much.(Yes I'm lazy)
Actually you dont need this part:
,"int",1,"cdecl") We could create a caller function that does the thing we want.
In order to use the stdcall convention(Wich is the standard for the DllCall function) you have to put a _stdcall before the function.
Your C++ code will look like this:
Code: Select all
unsigned int MyFunction(unsigned int a,unsigned int b)
{
if (a>0)
return MyFunction(a-1,b*a);
else
return b;
}
unsigned int _stdcall MyFunctionCaller(unsigned int a)
{
return MyFunction(a,1);
}
The result:
Code: Select all
MyFunction := MCode("2,x86:i0wkBItEJAiFyXQKjWQkAA+vwUl1+sM=,x64:hcl0Bw+v0f/JdfmLwsM=")
MyFunctionCaller := MCode("
(LTrim Join
2,x86:i0QkBIXAdA5QSFDoAAAAAIPECMIEALgBAAAAwgQA,x64:i9GFyXQH/8npAAAAALgBAAAAww==
)")
Msgbox % DllCall(MyFunctionCaller,"uint",3)
But the Messagebox is empty.
No we didn't make a mistake. The Problems name is MCode:
OK Lets imagine you have a AHK script, but you have to call every function by its position: (e.g. call Char nr. 144.).
This is where your function starts at Char 144.
Now lets imagine we put some new code in front of your function.
Your function will be moved backwards e.g. 20 Chars.
If you don't change the starting nr. of your function you wont be able to call it properly.
In Machine Code it is exactly like this:
A function is called by calling the start address of the function.
But the function is added after the AHK stuff.
That's why your function is calling something else. This leads to errors.
The compiler is able to tell you the starting address it expected:
(Note: Not for 64 bit PCs)
Code: Select all
/*
unsigned int MyFunction(unsigned int a,unsigned int b)
{
if (a>0)
return MyFunction(a-1,b*a);
else
return b;
}
unsigned int MyFunctionaddress()
{
return (unsigned int)(&MyFunction);
}
*/
MyFunction := MCode("2,x86:i0wkBItEJAiFyXQKjWQkAA+vwUl1+sM=,x64:hcl0Bw+v0f/JdfmLwsM=")
MyFunctionaddress := MCode("2,x86:uAAAAADD,x64:SI0FAAAAAMM=")
Msgbox % "The expected Address of the function is :" DllCall(MyFunctionaddress)
Msgbox % "The actual address of the function is :" MyFunction
So you cant call functions in a normal way.
So what do we do now
The answer is function pointers.
...
Functionpointers are documented here:
http://www.cplusplus.com/doc/tutorial/pointers/
Please read through the site mentioned before reading further.
To call our function in MCode we have to give it the pointer to our function.
Code: Select all
unsigned int MyFunction(unsigned int a,unsigned int b)
{
if (a>0)
return MyFunction(a-1,b*a);
else
return b;
}
unsigned int _stdcall MyFunctionCaller(unsigned int a,unsigned int(*MyFunction)(unsigned int,unsigned int) )
{
return (*MyFunction)(a,1);
}
Results in:
Code: Select all
MyFunction := MCode("2,x86:i0wkBItEJAiFyXQKjWQkAA+vwUl1+sM=,x64:hcl0Bw+v0f/JdfmLwsM=")
MyFunctionCaller := MCode("2,x86:i0QkBGoBUP9UJBCDxAjCCAA=,x64:SIvCugEAAABI/+A=")
When we call the new function we also have to add the Function pointer.
Code: Select all
MyFunction := MCode("2,x86:i0wkBItEJAiFyXQKjWQkAA+vwUl1+sM=,x64:hcl0Bw+v0f/JdfmLwsM=")
MyFunctionCaller := MCode("2,x86:i0QkBGoBUP9UJBCDxAjCCAA=,x64:SIvCugEAAABI/+A=")
Msgbox % DllCall(MyFunctionCaller,"uint", 3,"UPtr",MyFunction)
6 was expected and if you did everything right it should be the result.