我正在学习如何使用c ++在游戏服务器中挂钩一些函数,我看到了一个直接从指针调用函数的代码。
这是我看到的代码:
#define DataRecv ((void(*) (BYTE, PBYTE, DWORD, DWORD,…)) 0x004368E0)
这是我的代码:
#define LoadMoveLevel ((void(*) (char *)) 0x0051DF70)
如何调用函数LoadMoveLevel? 我试过了:
MessageBoxA(NULL, LoadMoveLevel("teste"), "example", MB_OK);
但得到此错误:类型void的参数与参数类型LPCSTR
不兼容感谢。
答案 0 :(得分:1)
根据MessageBoxA
的定义,
int WINAPI MessageBox(
_In_opt_ HWND hWnd,
_In_opt_ LPCTSTR lpText,
_In_opt_ LPCTSTR lpCaption,
_In_ UINT uType);
当您致电MessageBoxA(NULL, LoadMoveLevel("teste"), "example", MB_OK);
时,第二个参数需要LPCTSTR
,但您可以通过
void
#define LoadMoveLevel ((void(*) (char *)) 0x0051DF70)
答案 1 :(得分:1)
根据documentation,MessageBoxA
函数具有以下签名:
int WINAPI MessageBox(
_In_opt_ HWND hWnd,
_In_opt_ LPCTSTR lpText,
_In_opt_ LPCTSTR lpCaption,
In UINT uType
);
您可以看到第二个参数的类型为LPCTSTR
,但您的函数返回void
。因此,您无法在第二个参数中调用它,因为它不返回所需的类型。
#define LoadMoveLevel ((void(*) (char *)) 0x0051DF70)
// ^^^^ // This is the return type of the function
注意:消息框函数名称后面的“A”表示您使用的是ANSI版本(而不是UNICODE版本),第二个参数实际上是LPCSTR
(例如,const char*
)在你的情况下。
由于R Sahu提到将其作为参数调用消息框函数,因此需要将返回类型从void
更改为适当的类型。
答案 2 :(得分:1)
首先加载界面:#include "MoveCommand.h"
然后以正确的名称调用该函数:gMoveCommand.LoadMoveLevel("teste");
返回值仍然是int
,而不是char*
。请参阅服务器文档以了解正确使用方法。
(看#define DataRecv
之类的东西会让我逃避一个项目。不要把这个muOnline克隆作为一个好的,甚至是有效的C ++的例子。)
答案 3 :(得分:0)
MessageBoxA
的第二个参数是LPCSTR
类型。您定义LoadMoveLevel
的方式,LoadMoveLevel("teste")
的返回值为void
。这就是编译器抱怨的内容。
如果生活在地址0x0051DF70
的函数确实应该返回void
,则无法使用LoadMoveLevel
。如果该函数应该返回LPCSTR
,则必须将LoadMoveLevel
更改为:
#define LoadMoveLevel ((LPCSTR (*) (char *)) 0x0051DF70)
然后是电话
MessageBoxA(NULL, LoadMoveLevel("teste"), "example", MB_OK);
应该有用。
答案 4 :(得分:0)
您已通过指向返回void
的函数的指针将LoadMoveLevel()定义为调用。 MessageBoxA()
的第二个参数是(const
)char *
。从函数返回void
不会产生任何值,因此无法转换为任何值。因此错误。
宏正在做的是将值转换为指针(到函数),然后调用函数。要使其编译,请将宏更改为
#define LoadMoveLevel ((LPCSTR (*) (char *)) 0x0051DF70)
或(将LPCSTR
扩展到
#define LoadMoveLevel (((char *) (*) (char *)) 0x0051DF70)
请注意,您正在做的事情非常危险。将任意值转换为函数指针以便调用它依赖于那里的ACTUALLY是该位置的有效代码。如果您不理解语法(根据您的问题),您可能不知道如何确保该位置的代码对应于接受char *
作为参数的函数,并返回{{} 1}}。