C ++如何使一个函数只运行一个

C++ How to make that a function runs only one

我在 Visual Studio 2017.At 中使用了一个 C++\CLR 项目,当时我试图操纵内存,所以我为一个无名游戏创建了一个 hack 并尝试操纵游戏。

我的问题是我尝试创建一个随机整数,为此我将函数 rand() 与 firstSetRand srand().

结合使用
using namespace System;

    int * randomName()
        {
    srand((unsigned)time(0));
        int i = 1;
        static int name[5];
        for (int i = 1; i < 5; i++)
            {
                name[i] = 97 + rand() % 122;
            }
            std::cout << name << std::endl;
            return name;
        }

这是我的随机计数函数,在这里我称之为:

int main(array<System::String ^> ^args)
{
while (true)
    {
      switch (inputCheat)   //check which case match with the user input
                {
                    case 4:
                        Console::WriteLine("test: ");
                        random:: randomName(firstSetRand);
                        //WriteProcessMemory(handle, (LPVOID)localName, &inputNumber, sizeof(), NULL); //Write to the local adress memory and change the value
                        Console::WriteLine("\nWhat did you want to cheat up: ");
                        break;
       }
    }
Sleep(200);
}

问题是因为那是一个 while(true) 循环,我多次调用该函数。而且我不知道如何使 srand() 函数只调用一次,我总是得到相同的随机数。

我来自Java。在 Java 中,我会在 class 中完成整个代码,然后在构造函数中编写变量,但我认为这在 C++ 中是不可能的。因为当我在 class 中执行整个代码时,我得到了错误:

Severity Code Description Project File Line Suppression State
Error LNK2019 unresolved external symbol _main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) AssaultCubeHack C:\Users\schup\source\repos\AssaultCubeHack\AssaultCubeHack\MSVCRTD.lib(exe_main.obj)   1

这里是我项目的完整代码:

// AssaultCubeWithClr.cpp: Hauptprojektdatei.


#include "stdafx.h"

using namespace System;

struct InitRandHelper
{
    InitRandHelper() { srand((unsigned)time(0)); }
};

int * randomName()
    {
    static InitRandHelper init;

    int i = 1;
    static int name[5];
    for (int i = 1; i < 5; i++)
        {
            name[i] = 97 + rand() % 122;
        }
        std::cout << name << std::endl;
        return name;
    }

void StartText()
{
    //Text to See in the Console
    Console::ForegroundColor = System::ConsoleColor::Green;
    Console::WriteLine("Welcome to my Cheat for AssaultCube!");
    Console::WriteLine("------------------------------------");
    Console::WriteLine("1. For More Health type in: 1.");
    Console::WriteLine("2. For More Ammo type in: 2");
    Console::WriteLine("3. For More Armor type in: 3");
    Console::WriteLine("4. For Turn on Name changer: 4");
}
int main(array<System::String ^> ^args)
{
    DWORD playerBaseAdress = 0x00509b74;
    DWORD offsePrimaryAmmo = 0x128;
    DWORD offsetPistolAmmo = 0x13C;
    DWORD offsetArmor = 0xFC;
    DWORD offsetHealth = 0xF8;
    DWORD offsetRoll = 0x0080;
    DWORD baseforName = 0x005028FC;

    static bool firstSetRand = true;

    int inputCheat;
    int inputNumber;
    DWORD processId;
    DWORD localPlayer;
    DWORD localName;
    DWORD primaryAmmo;
    DWORD pistolAmmo;
    DWORD health;
    DWORD armor;
    DWORD roll;

    bool firstExecute = true;

    HWND hwnd = FindWindowA(NULL, "AssaultCube");       //Find Window with Name AssaultCube

    StartText();        //function call
    while (true)
    {

        if (hwnd == NULL)   //Check if the game exists
        {
            if (firstExecute == true)
            {
                Console::ForegroundColor = System::ConsoleColor::Red;
                Console::WriteLine("ERROR: The Game couldn´t found!");
                firstExecute = false;
            } 
        }
        else
        {
            GetWindowThreadProcessId(hwnd, &processId);     //Get Process id from the Window
            HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, false, processId);

            if (handle == NULL) //check if process id exsits
            {
                Console::ForegroundColor = System::ConsoleColor::Red;
                Console::WriteLine("ERROR: Wrong Process Id!");
                Console::ForegroundColor = System::ConsoleColor::Green;
            }
            else
            {
                ReadProcessMemory(handle, (LPCVOID)playerBaseAdress, &localPlayer, sizeof(playerBaseAdress), NULL); //Read the local adresse and save it in localPlayer
                ReadProcessMemory(handle, (LPCVOID)baseforName, &localName, sizeof(playerBaseAdress), NULL);

                primaryAmmo = localPlayer + offsePrimaryAmmo;
                pistolAmmo = localPlayer + offsetPistolAmmo;
                health = localPlayer + offsetHealth;
                armor = localPlayer + offsetArmor;
                roll = localPlayer + offsetRoll;

                std::cin >> inputCheat;     //wait for user input

                switch (inputCheat)         //check which case match with the user input
                {
                    case 1:
                        Console::WriteLine("Write how much Health you want: ");
                        std::cin >> inputNumber;
                        WriteProcessMemory(handle, (LPVOID)health, &inputNumber, sizeof(inputNumber), NULL); //Write to the local adress memory and change the value
                        Console::WriteLine("\nWhat did you want to cheat up: ");
                        break;

                    case 2:
                        Console::WriteLine("Write how much Ammo you want: ");
                        std::cin >> inputNumber;
                        WriteProcessMemory(handle, (LPVOID)primaryAmmo, &inputNumber, sizeof(inputNumber), NULL); //Write to the local adress memory and change the value
                        Console::WriteLine("\nWhat did you want to cheat up: ");
                        break;

                    case 3:
                        Console::WriteLine("Write how much Armor you want: ");
                        std::cin >> inputNumber;
                        WriteProcessMemory(handle, (LPVOID)armor, &inputNumber, sizeof(inputNumber), NULL); //Write to the local adress memory and change the value
                        Console::WriteLine("\nWhat did you want to cheat up: ");
                        break;

                    case 4:
                        Console::WriteLine("Random Number: ");
                        randomName();
                        //WriteProcessMemory(handle, (LPVOID)localName, &inputNumber, sizeof(), NULL); //Write to the local adress memory and change the value
                        Console::WriteLine("\nWhat did you want to cheat up: ");
                        break;

                    case 5:
                        Console::WriteLine("test: ");
                        std::cin >> inputNumber;
                        WriteProcessMemory(handle, (LPVOID)roll, &inputNumber, sizeof(inputNumber), NULL); //Write to the local adress memory and change the value
                        Console::WriteLine("\nWhat did you want to cheat up: ");
                        break;

                    default:
                        Console::ForegroundColor = System::ConsoleColor::Red;
                        Console::WriteLine("ERROR: Wrong Entry!");
                        Console::WriteLine("Try a other input :D");
                        Console::ForegroundColor = System::ConsoleColor::Green;
                        break;
                }
            }
        }
        Sleep(200);
    } 
    return 0;
}

在这里你可以看到它不起作用。

解决方案 1

您可以为此使用函数 static 变量。

static bool firstTime = true;
if ( firstTime )
{
    srand((unsigned)time(0));
    firstTime = false;
}

解决方案 2

如果你不想为每次调用函数支付检查的代价,你可以使用一个助手class/struct。

struct InitRandHelper
{
   InitRandHelper() { srand((unsigned)time(0)); }
};


int* randomName()
{
   // Initialize the random number generator.
   static InitRandHelper init;

   int i = 1;
   static int name[5];
   for (int i = 1; i < 5; i++)
   {
      name[i] = 97 + rand() % 122;
   }
   std::cout << name << std::endl;
   return name;
}

解决方案 3

while 循环开始之前在 main 中调用 srand

int main(array<System::String ^> ^args)
{
   srand((unsigned)time(0));

   while (true)
   {
      switch (inputCheat)   //check which case match with the user input
      {
         case 4:
            Console::WriteLine("test: ");
            random:: randomName(firstSetRand);
            //WriteProcessMemory(handle, (LPVOID)localName, &inputNumber, sizeof(), NULL); //Write to the local adress memory and change the value
            Console::WriteLine("\nWhat did you want to cheat up: ");
            break;
      }
   }
   Sleep(200);
}

并删除来自 random::randomName 的调用。

好的,这里是我找到的答案。问题是这一行:

 std::cout << name << std::endl;

控制台中的输出不是值,而是数组中的地址。为了正确地做到这一点,我必须这样做:

    int i = 1;
       static int name[5];
       for (int i = 1; i < 5; i++)
       {
          name[i] = 97 + rand() % 122;
          std::cout << name[i] << std::endl; //this line is the right thing to do it
       }
       return name;