Странное поведение заголовочных файлов в C++
Вообщем, я пытался запихнуть все заголовки в один файл, что бы не получать ошибки от линкера. Но, я столкнулся с проблемой: Оба Hooks.h и Visuals.h были включены в один и тот же файл, Hooks.h не имеет ошибок. Ни со стороны компилятора, ни с интеллисенса.
#pragma once
namespace Hooks {
// VMTHook, Включенный в родительском файле, здесь есть.
// Более того, IDirect3DDevice тоже здесь есть, тоже самое и с HRESULT.
VMTHook D3DDeviceHooks;
VMTHook CHLClientHooks;
VMTHook ClientModeHooks;
/**
* Setups all the hooks.
*/
void SetupHooks() {
D3DDeviceHooks = VMTHook(g_pD3ddevice);
CHLClientHooks = VMTHook(g_pClient);
ClientModeHooks = VMTHook(g_pClientmode);
Visuals::Hooks::orgEndScene = (Visuals::Hooks::EndSceneFn)D3DDeviceHooks.HookFunction(42, Visuals::Hooks::hookEndScene);
}
}
Однако, в Visuals.h начинаются проблемы. Включения, которые я сделал в родительском заголовке, на этот файл не распостраняются. Сам компилятор дает мне отчет о том, что в файле ошибки. Какие - смотрите в коде.
#pragma once
namespace Visuals {
namespace Hooks {
typedef HRESULT(__stdcall* EndSceneFn)(IDirect3DDevice9*);
// IDirect3DDevice9 не определен, HRESULT тоже
EndSceneFn orgEndScene = nullptr;
HRESULT __stdcall hookEndScene(IDirect3DDevice9* device)
{
if (!Visuals::Initialized)
Visuals::Initialize(device);
Visuals::Draw(g_pGlobalvars->frametime);
return orgEndScene(device);
}
WNDPROC orgWndProc = 0;
// WNDPROC не определен
LRESULT __stdcall hookWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if ((msg == WM_KEYDOWN || msg == WM_KEYUP) && (wParam == Visuals::Menu::Variables::MenuHotkey)) {
Visuals::Menu::Open();
}
return CallWindowProcA(orgWndProc, hwnd, msg, wParam, lParam);
}
}
...
Вот файл, в который они включены:
... // Здесь много включений, таких как "windows" и "d3d9"
#include "sdk/Definitions.h"
#include "Utils/PatternScans.h"
#include "Visuals.h"
#include "Menu.h"
#include "VMTHook.h"
#include "Hooks.h"
Вы, возможно, можете испытать ту же проблему у себя, повторив эти действия:
- Создайте простой проект Visual Studio 2017 (MSVC Компилятор)
- Создайте заголовочный файл, создайте еще 2
- Включите оба созданных вами файла в первый
#include "header1.h"
#include "header2.h"
- В этот же файл добавьте пару включений, по типу "stdio"
#include "stdio.h"
#include "header1.h"
#include "header2.h"
- Проверьте наличие каких либо недостающих определений из stdio в этих файлах.
// Header 1
void Func1(){
printf("abc1\n");
}
// Header 2
void Func2(){
printf("abc2\n");
}