영상을 불러오지 못했습니다

Unreal C++ Interface 64개 제한과 C2607 진단

803 단어
4 분
Unreal C++ Interface 64개 제한과 C2607 진단

많은 Unreal Interface를 구현한 클래스에서는 generated code를 컴파일할 때 아래와 비슷한 오류가 발생하기도 한다.

error C2607: static assertion failed
UE_ARRAY_COUNT(Z_Construct_UClass_..._Statics::InterfaceParams) < 64

문제 현상#

오류는 직접 작성한 .cpp가 아니라 .gen.cpp의 FImplementedInterfaceParams 배열과 FClassParams 초기화 부근에서 난다. 처음에는 UHT 생성 오류처럼 보이지만 실제 입력은 클래스가 구현한다고 선언한 reflected interface 집합이다.

적용 범위#

이 제한은 오류를 만든 정확한 엔진 버전의 생성 코드와 FClassParams 표현에 종속된다. 원문 사례에서는 구현 interface 개수를 담는 필드가 6비트로 표현됐고 generated code가 64 미만을 요구했다. 최신 버전에서도 같은 숫자라고 가정해서는 안 된다. 설치한 엔진의 generated code와 Class.h를 확인해야 한다.

원인#

하나의 UCLASS가 직접 또는 부모 클래스를 통해 구현하는 reflected Unreal Interface의 총수가 해당 버전의 표현 한계를 넘었다. C++ 다중 상속 목록만 세면 부족하다. 부모 클래스가 구현한 interface와 Blueprint 계층에서 추가된 interface도 최종 class metadata에 포함되기도 한다.

재현 및 진단#

  1. 오류가 난 .gen.cpp에서 InterfaceParams 배열 항목을 센다.
  2. 직접 구현한 interface와 상속받은 interface를 분리해 목록화한다.
  3. Blueprint 자식이 아니라 native class 생성 중 실패했는지 확인한다.
  4. 설치한 엔진 source에서 static assertion과 개수 필드의 정의를 확인한다.
  5. 최근 추가한 interface를 제거했을 때 경계 아래로 내려가는지 최소 재현한다.

해결 방법#

가장 안전하게 해결하려면 한 클래스가 구현하는 interface 수를 줄인다.

  • 기능별로 component를 두고 interface 구현을 component로 이동한다.
  • 매우 작은 interface 여러 개가 항상 함께 쓰인다면 응집도 높은 하나의 계약으로 합친다.
  • 단순 질의는 gameplay tag, capability registry 또는 명시적 component 조회로 대체한다.
  • 상속 계층의 중복 interface 선언을 제거한다.

엔진의 bit field나 assertion을 넓히려면 engine fork 전체에서 reflection ABI와 serialization에 미치는 영향을 검토해야 한다. 프로젝트 코드만 컴파일되게 숫자를 바꾸는 임시 수정으로 취급해서는 안 된다.

검증 방법#

  • clean UHT/build에서 generated code가 다시 생성되는지 확인한다.
  • C++와 Blueprint 양쪽에서 ImplementsInterface와 interface call이 정상인지 검사한다.
  • cooked build에서 class load와 Blueprint compile을 확인한다.
  • interface를 component로 옮겼다면 복제·저장·수명 주기 동작도 회귀 테스트한다.

주의점#

이 문제는 “C++는 최대 64개만 상속할 수 있다”는 일반 언어 제한이 아니다. Unreal reflection metadata에 구현 interface 목록을 저장하는 특정 엔진 구현의 제한이다. 정확한 버전의 근거를 확보하기 전에는 제한값을 보편 규칙처럼 문서화하지 않는 편이 안전하다.

참고 자료#

글 공유하기

이 글이 도움이 되셨다면 다른 사람과 공유해 주세요!

Unreal C++ Interface 64개 제한과 C2607 진단
https://hon454.github.io/posts/unreal-engine-interface-limit-static-assert/
작성자
Jihoon Jeon
게시일
2023-12-19
라이선스
CC BY-NC-SA 4.0
관련 게시글스마트
1
Unreal Engine - Replication Graph
Unreal EngineUE 5.8.3 소스와 테스트 프로젝트 실측으로 Replication Graph가 기본 드라이버의 무엇을 줄이고 무엇을 줄이지 않는지 확인한다. 액터 5,000개와 클라이언트 16개까지의 측정, 효과가 있는 설정값과 이름과 반대로 동작하는 설정값, 커스텀 그래프의 라우팅과 Team Node, 5.8.3에서 재현한 버그 다섯 가지, 도입 기준과 Iris와의 관계를 다룬다.
2
Unreal Engine - Push Model Networking
Unreal EngineUE 5.8.3 기준으로 레거시 복제의 Push Model이 켜지는 조건, dirty 비트가 소비되는 경로, net.PushModelSkipUndirtiedReplication이 건너뛰는 범위를 엔진 소스로 확인하고, ThirdPerson 템플릿에 액터 1000개를 띄워 Unreal Insights, Networking Insights, Network Profiler로 CPU 시간, 대역폭, 비교 횟수를 측정한다. 같은 조건에서 Dormancy와도 비교한다.
3
면접 오답노트: 말하지 못한 주요 개념, Net Relevancy
Unreal Engine면접에서 제대로 답하지 못한 Net Relevancy를 다시 정리한다. AActor::IsNetRelevantFor의 판정 순서와 문서와 다른 부분, Owner가 판정을 바꾸는 방식, 연관성을 잃고 되찾을 때 RelevantTimeout과 액터 파괴, BeginPlay, OnRep, RPC에 생기는 일, ForceNetRelevant와 Replication Graph, Iris에서의 주의점, Dormancy, Priority와의 차이를 다룬다.
4
Unreal Engine PIE에서 클라이언트와 서버 값을 한 줄로 비교하기
Unreal EnginePIE에서 클라이언트 코드가 같은 프로세스의 서버 월드와 서버 측 PlayerController를 찾아 위치·속도를 한 줄로 비교하는 에디터 전용 디버그 코드와, 네트워크 에뮬레이션으로 확인한 측정 결과를 정리합니다.
5
휴면 액터 깨우기: FlushNetDormancy, ForceNetUpdate, SetNetDormancy
Unreal EngineUE 5.8.3 엔진 소스 기준으로 FlushNetDormancy, ForceNetUpdate, SetNetDormancy가 각각 무엇을 바꾸는지 비교한다. 휴면 정책과 휴면 상태의 차이, ForceNetUpdate가 덤으로 하는 flush가 빠지는 조건, 값을 바꾼 뒤 깨우면 FastArray 변경이 사라지는 문제, 이를 막는 setter 패턴과 Push Model을 함께 쓸 때의 주의점을 정리한다.
무작위 게시글무작위

댓글

Profile Image of the Author
Jihoon Jeon
안녕하세요! 서브컬처와 자전거를 사랑하는 개발자 전지훈입니다.
공지사항
제 블로그에 오신 것을 환영합니다! 예시 공지입니다.
카테고리
태그
최신 일상
사이트 통계
게시글
73
카테고리
10
태그
143
총 단어 수
133,527
운영 일수
0일
최근 활동
0일 전
사이트 정보
빌드 플랫폼
GitHub Actions
블로그 버전
Firefly v6.16.9
라이선스
CC BY-NC-SA 4.0
목차