我目前正在通过DLL Injection为GTA San Andreas制作一个mod。我有如下所示的功能,向玩家展示游戏中的消息框。
void showDialog (int send, int dialogID, int typedialog, char * caption,
const char * text, char * button1, char * button2)
{
uint32_t func = pSAMP + SAMP_DIALOG_SHOW; //pSAMP = DWORD base of samp.dll
uint32_t data = pSAMP + SAMP_DIALOG_INFO_OFFSET;
__asm mov eax, dword ptr [data]
__asm mov ecx, dword ptr [eax]
__asm push send
__asm push button2
__asm push button1
__asm push text
__asm push caption
__asm push typedialog
__asm push dialogID
__asm call func
}
消息框中包含的文本是在开始游戏时动态创建的,方法是从空global std::string
开始(例如,std::string string;
)并使用string::append()
创建所需的字符串。在初始创建之后,程序中的任何地方都不会编辑该字符串。
按下某个键后,将调用showDialog()
函数:
showDialog(0, 2 , 2, "MYTITLE", string.c_str(), "OK", "CLOSE");
大约50%的时间,此代码将完美运行,显示所需的文本,并且通常如果游戏对话框在第一次调用时正确显示,则每次调用它时都会完美地运行。< / p>
剩余的50%,当调用此showDialog()
函数时,游戏将立即冻结而不显示对话框。没有给出错误报告或寄存器,游戏在当前帧冻结。退出游戏的唯一方法是退出Windows,因为没有其他进程窗口可用。有时在按键和游戏冻结之间会有约5秒的延迟,而游戏中不会显示消息框。
如果通过在调用函数时指定showDialog()
来调用static string
,例如:
showDialog(0, 2 , 2, "MYTITLE", "MY TEXT", "OK", "CLOSE");
它会正常运行而不会冻结。我假设这排除了showDialog()
函数不正确的可能性。
我的问题是,冻结的声音是否是因为某种方式与我使用char*
,std::string
,.c_str()
等相关联的内存损坏造成的?有没有人建议我如何在不冻结游戏的情况下使这个代码工作?