Идентификатор (_T) L не определен
#define _T(x) L ## x
#else /* _UNICODE */
#define _T(x) x
#endif /* _UNICODE */
#include <Windows.h>
#include <iostream>
#include <TlHelp32.h>
#include <vector>
#include <Psapi.h>
#include <tchar.h>
using namespace std;
DWORD GetModuleBaseAddress(TCHAR* lpszModuleName, DWORD pID) {
DWORD dwModuleBaseAddress = 0;
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pID); // make snapshot of all modules within process
MODULEENTRY32 ModuleEntry32 = { 0 };
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &ModuleEntry32)) //store first Module in ModuleEntry32
{
do {
if (_tcscmp(ModuleEntry32.szModule, lpszModuleName) == 0) // if Found Module matches Module we look for -> done!
{
dwModuleBaseAddress = (DWORD)ModuleEntry32.modBaseAddr;
break;
}
} while (Module32Next(hSnapshot, &ModuleEntry32)); // go through Module entries in Snapshot and store in ModuleEntry32
}
CloseHandle(hSnapshot);
return dwModuleBaseAddress;
}
int main() {
HWND hWnd = FindWindowA(0, ("Arma 3 \"E:\\SteamLibrary\\steamapps\\common\\asfasf\\asfasfa\" \"-name=Timur Pena\" -mod="));
if (!hWnd) //If none, display an error
{
cout << "Window not found!\n";
cin.get();
}
GetWindowThreadProcessId(hWnd, &pID);
HANDLE pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
if (pHandle == INVALID_HANDLE_VALUE || pHandle == NULL)
{
cout << "Failed to open Process!\n";
cin.get();
return 0;
}
cout << "Process ID:" << pID << "\n";
const char gameName[] = ("faasfasfagg");
DWORD gameBaseAddr =GetModuleBaseAddress(_T(gameName), pID);
cout << gameBaseAddr
}
Вот мой код, хочу найти базовый адресс процесса по имени и id процесса, но VS в строчке
DWORD gameBaseAddr =GetModuleBaseAddress(_T(gameName), pID);
пишет идентификатор "Lgamename" не определен. Что делать? К слову я видел как этот же код работает у других людей, пробовал и пастить, то, что было у людей - ошибка все такая же.
Ответы (2 шт):
При сборке программы первым делом в игру вступает препроцессор, который видит строку:
DWORD gameBaseAddr = GetModuleBaseAddress(_T(gameName), pID);
И думает: "Ага! Надо раскрыть макрос, а макрос этот - конкатенация двух токенов", - макрос раскрывается так:
_T(gameName) -> L ## gameName -> LgameName
Напомню: препроцессор работает с токенами (лексемами) и ничего не знает о семантике и значениях.
В итоге выходит так, что указанная строчка компилятору отдается в таком виде:
DWORD gameBaseAddr = GetModuleBaseAddress(LgameName, pID);
Ну а идентификатор LgameName нигде не определен - отсюда и ошибка компиляции.
Если хочется поддерживать и ансишную и юникодную версии, то надо вот так поступить:
const TCHAR gameName[] = _T("faasfasfagg"); // или auto
DWORD gameBaseAddr =GetModuleBaseAddress(gameName, pID);
Но сейчас уже нет смысла поддерживать две версии параллельно - это было актуально давно. Сейчас можно просто поддерживать только юникодную версию:
const wchar_t gameName[] = L"faasfasfagg";
DWORD gameBaseAddr =GetModuleBaseAddress(gameName, pID);
Соответственно и использовать можно юникодные функции:
wcscmpвместо_tcscmpFindWindowвместоFindWindowA(ну вообще это макрос, который в юникодном проекте раскроется вFindWindowW)
Поток вывода тоже на wcout поменять можно. Ну и это влечет использование везде wchar_t вместо char или TCHAR.
Для перевода строк между юникодом и анси в рантайме можно использовать MultiByteToWideChar.
К слову, майкрософт вроде определяет макрос _T у себя (если нет, то аналогичный по функционалу TEXT точно есть).