Reputation: 458
I'm learning how to hook some functions in a gameserver using c++ and I saw a code that call a function directly from a pointer.
Here's the code that I saw :
#define DataRecv ((void(*) (BYTE, PBYTE, DWORD, DWORD,…)) 0x004368E0)
Here's my code:
#define LoadMoveLevel ((void(*) (char *)) 0x0051DF70)
How I can call the function LoadMoveLevel? I tried that :
MessageBoxA(NULL, LoadMoveLevel("teste"), "example", MB_OK);
but get this error : Argument of type void is imcompatible with parameter type LPCSTR
Thanks.
Upvotes: 0
Views: 114
Reputation: 137780
First load the interface: #include "MoveCommand.h"
Then call the function by its proper name: gMoveCommand.LoadMoveLevel("teste");
The return value is still an int
, not a char*
. Please refer to the server documentation to learn about proper usage.
(Seeing something like #define DataRecv
would cause me to run away from a project. Do not take any of this muOnline clone as an example of good, or even valid, C++.)
Upvotes: 1
Reputation: 9602
Per the documentation the MessageBoxA
function has the following signature:
int WINAPI MessageBox(
_In_opt_ HWND hWnd,
_In_opt_ LPCTSTR lpText,
_In_opt_ LPCTSTR lpCaption,
In UINT uType
);
You can see that the 2nd argument is of type LPCTSTR
but you're function returns void
. Therefore, you cannot call it in the 2nd parameter because it does not return the required type.
#define LoadMoveLevel ((void(*) (char *)) 0x0051DF70)
// ^^^^ // This is the return type of the function
Note: The 'A' appended to the message box function name means you're using the ANSI version (as opposed the the UNICODE version) and the 2nd argument is actually LPCSTR
(i.e., const char*
) in your case.
As R Sahu mentions to call it as a parameter the the message box function the return type would need to be changed from void
to the appropriate type.
Upvotes: 1
Reputation: 36597
You have defined LoadMoveLevel() to be a call via a pointer to a function that returns void
. The second argument of MessageBoxA()
is a (const
) char *
. A return of void
from a function does not yield any value, so cannot be converted to anything. Hence the error.
What the macro is doing is converting the value to a pointer (to function) and then calling the function. To make it compile, change your macro to either
#define LoadMoveLevel ((LPCSTR (*) (char *)) 0x0051DF70)
or (expanding LPCSTR
) to
#define LoadMoveLevel (((char *) (*) (char *)) 0x0051DF70)
Note that what you are doing is extremely dangerous. Converting an arbitrary value to a function pointer in order to call it relies on there ACTUALLY being valid code at that location. Odds are, if you do not understand the syntax (as per your question) you do not know how to ensure that the code at that location corresponds to a function that accepts a char *
as an argument, and returns a char *
.
Upvotes: 0
Reputation: 1924
According to definition of MessageBoxA
,
int WINAPI MessageBox(
_In_opt_ HWND hWnd,
_In_opt_ LPCTSTR lpText,
_In_opt_ LPCTSTR lpCaption,
_In_ UINT uType);
When you call MessageBoxA(NULL, LoadMoveLevel("teste"), "example", MB_OK);
, the 2nd parameter needs a LPCTSTR
, but you return void
by
#define LoadMoveLevel ((void(*) (char *)) 0x0051DF70)
Upvotes: 1
Reputation: 206567
The second argument of MessageBoxA
is of type LPCSTR
. The way you have defined LoadMoveLevel
, the return value of LoadMoveLevel("teste")
is void
. That's what the compiler is complaining about.
If the function that lives at the address 0x0051DF70
is supposed to return void
indeed, you cannot use LoadMoveLevel
. If that function is supposed to return a LPCSTR
, then, you have to change LoadMoveLevel
to:
#define LoadMoveLevel ((LPCSTR (*) (char *)) 0x0051DF70)
and then, the call
MessageBoxA(NULL, LoadMoveLevel("teste"), "example", MB_OK);
should work.
Upvotes: 0