작성
·
310
0
지난번에 어디서 오타를 내거나 했나보다 하고 그냥 복붙하고 해결했는데요! 이게 발생조건을 알았는데, 막상 해결방법이 떠오르질 않아서 다시 질문드립니다
Types에서 #define _STOMP 를 주석처리하는 순간 바로 이 에러가 발생해버립니다. 현재 PacketSession의 코드를 다운받아서 #define _STOMP만 주석처리해도 바로 발생하네요.
이게 GSessionManager 이전까지 제가 _STOMP를 주석처리 시켜두고 계속해서 코드진행을 해왔고 에러가 발생하지 않았는데, GSessionManager 추가 이후부터 에러가 발생했고, 당시에는 원인을 알 수 없어서 복붙으로 해결했는데, 기존 코드에서는 STOMP가 켜져있었고, 그냥 Pool에서 가져다쓰게 하고싶어서 STOMP를 끄니 바로 에러가 발생해서 발견했습니다.
예전 강의에서 언급하셨듯이 컴파일러가 사용되지 않는 전역변수는 아예 컴파일도 안해버린다고 했던 문제와 연관이 있는 것 같은데 원인은 역시 전혀 모르겠습니다ㅠ
답변 2
0
아~ 이해했습니다.
그냥 말 그대로 CoreGlobals가 생성되기 이전에
GSessionManager가 생성되어서 메모리 풀을 사용하지 못하는 상황이군요.
그런 상황이라면, 메모리 풀을 사용하지 않거나,
아니면 객체 생성을 전역 CoreGlobals 다음에 생성되게 유도해주시면 되겠습니다.
전역 객체끼리의 생성 순서는 우리가 직접 조작하기 힘들기 때문에
그냥 속편히 main에서 직접 new를 해주는게 편리합니다.
옵션 1) 메모리풀 버전 제거
GameSessionManager의 _sessions를 메모리 풀 버전이 아닌 일반 unordered_map을 사용.
옵션 2)
extern GameSessionManager* GSessionManager; 로 수정해주고,
int main() 내부에서
GSessionManager = new GameSessionManager();호출
물론 기타 등등 다양한 방법은 많을테니 잘 응용해주시면 되겠습니다.
사실 C++ 컴파일 원리 쪽은 복잡한 주제라 언~~젠가 계획만 하고 있는 고급 C++ 시리즈에서 다룰 예정이고, Part1에서 그 정도로 상세한 부분은 다루지 않습니다 ^^; 서버 강의를 잘 따라오시는거 보니 굳이 Part1를 수강하실 필요는 없어 보입니다.
0
그냥 단순히 CoreGlobal 전역 객체가 만들어지지 않은 것으로 보이는데,
그 문제가 맞는지 breakpoint를 잡아서 살펴보시기 바랍니다.
안 만들어진다면 그냥 객체를 하나 만들어주시면 되겠습니다.
StompAllocator일 경우에는 GMemory에 breakpoint 잡아서 보면 또 _poolTable에 값이 제대로 들어가는걸로 봐서 할당자들 문제는 아닌 것 같습니다.
GameSessionManager에서 extern한 GSessionManager가 아직 전역 객체가 생성되지 않았을 때 전역 객체를 참조해서 에러가 발생하는 것 같은데, 이게 GameServer의 include 순서가 pch.h가 제일 위에 있기 때문에 순서 문제는 아닌 것 같고, 아마 컴파일 과정에서 include보다 솔루션 내의 전역변수를 먼저 초기화하는 느낌이 드는데 이런 컴파일 순서같은 기초지식들은 제가 c++강의를 안 듣고 바로 서버강의로 넘어와서 자세하게는 잘 모르겠네요ㅠ
어찌됐든 객체로 만드려다보니까 extern으로 GSessionManager를 내보내주는 걸 지우고 GameServer의 스택 메모리에서 선언하고 사용하려고 하니까, GSessionManager에 접근하는 GameSession 함수 전체에 바로 에러가 뜨는데 이 부분은 조금 더 시도해보다가 정 안되면 다시 질문드리겠습니다.
음~ 제 환경에선 한 번도 일어나지 않아서 어떤 상황인지 잘 모르겠네요.
강의 코드를 다운 받아 실행하시는건가요, 아니면 직접 코드를 작성하시는건가요?
만약 다르게 작성했는데 문제 나는 상황이라면 rookiss@naver.com로 보내주시면
제 환경에서도 테스트를 해보겠습니다.
강의 코드 다운 받아도 동일한 문제라면.. (먼산)
시도해본 방법으로
1) CoreGlobal에 GSessionManager 만들기 시도
이 방법은 조금 해보다가, CoreGlobal에서 #include GameSessionManager.h 를 하지 않으면 진행이 더 이상 되지 않아서 바로 포기했습니다.
2) GameSession에 _owner추가
GameSession에 멤버변수 GameSessionManager _owner를 만들어주고, 초기화 리스트로 _owner(GSessionManager)로 넘기는 방법을 시도해봤는데, GameSession 자체가 _sessionFactory를 통해서 동적으로 생성되기 때문에, ServerService의 3번째 매개변수인MakeShared<GameSession>에서 매개변수를 받을 방법이 생각나질 않아서
using SessionFactory = function<SessionRef(GameSessionManager)>; << 기존 매개변수 void
이런식으로 바꿔주고
ServerServiceRef service = cmake_shared<ServerService>(
NetAddress(L"127.0.0.1", 7777),
cmake_shared<IocpCore>(),
cmake_shared<GameSession>(GSessionManager), // TODO : SessionManager 등
100);
이렇게 Args를 밀어넣어줘서 게임세션 생성자로 주려고 해봤는데요
결국 Service::CreateSession 함수의 SessionRef session = _sessionFactory(); 이곳까지 어떻게 넘겨줄 방법이 딱히 안보여서 막혔습니다ㅠ
다른 방법은 제 수준으로는 아직 떠오르질 않았습니다ㅜ
그래도 PoolAllocator로 하고싶어서 옵션2로 해서 해결됐습니다ㅠㅠ 포인터로 extern하고 new로 받아주는건 생각못하고 그냥 어떻게든 객체 상태로 extern하다보니까 무슨 이상한 _sessionFactory까지 넘어갔었네요ㅎㅎㅎ 이게 기초강의 거르고 서버강의로 바로 온 업보...ㅠ 감사합니다!