디버그 모드에서는 링크 문제가 없는데 릴리즈 모드에서 링크 에러가 발생했다. 해당 라이브러리를 쓰는 다른 프로젝트는 문제가 없어서 lib 경로 문제인가 싶어서 이리저리 확인해 봤으나 원인을 찾을 수가 없었다. lib 에 정말 symbol 이 있는지 확인해 보고 싶어졌다. 

Visual Studio 에 포함된 dumpbin 을 이용하면 된다.

dumpbin /symbols [lib 파일명]

Visual Studio 에 포함된 libcmt.lib 를 까보면 이런 식으로 보인다.

dumpbin /symbols libcmt.lib


File Type: LIBRARY


COFF SYMBOL TABLE000 00C7A09E ABS    notype       Static       | @comp.id
001 00000011 ABS    notype       Static       | @feat.00
002 00000000 UNDEF  notype       External     | _strcat003 00000000 UNDEF  notype       WeakExternal | __mbscat

    Default index        2 Alias record

String Table Size = 0x0 bytes

COFF SYMBOL TABLE
000 00C7A09E ABS    notype       Static       | @comp.id
001 00000011 ABS    notype       Static       | @feat.00
002 00000000 UNDEF  notype       External     | _strcpy
003 00000000 UNDEF  notype       WeakExternal | __mbscpy

    Default index        2 Alias record

String Table Size = 0x0 bytes

COFF SYMBOL TABLE
000 00C7A09E ABS    notype       Static       | @comp.id
001 00000011 ABS    notype       Static       | @feat.00

...(생략)

0A4 00000000 SECT33 notype       External     | ??_C@_01EEMJAFIK@?6?$AA@ (`string')
0A5 00000000 SECT34 notype       Static       | .rdata    Section length    3, #relocs    0, #linenums    0, checksum BB71EC38, selection    2 (pick any)

0A7 00000000 SECT34 notype       External     | ??_C@_02LLMPMKNF@?$DO?5?$AA@ (`string')

0A8 00000000 SECT35 notype       Static       | .rdata

    Section length    9, #relocs    0, #linenums    0, checksum F5F13728, selection    2 (pick any)

0AA 00000000 SECT35 notype       External     | ??_C@_08OMAHNMHJ@?6Data?3?5?$DM?$AA@ (`string')

0AB 00000000 SECT36 notype       Static       | .rdata
    Section length   2A, #relocs    0, #linenums    0, checksum 21F15550, selection    2 (pick any)

0AD 00000000 SECT36 notype       External     | ??_C@_0CK@DKGBICFE@?6Allocation?5number?5within?5this?5f@ (`string')

0AE 00000000 SECT37 notype       Static       | .rdata

    Section length    8, #relocs    0, #linenums    0, checksum AFE40ACB, selection    2 (pick any)

0B0 00000000 SECT37 notype       External     | ??_C@_07DFDJCKFN@?6Size?3?5?$AA@ (`string')
0B1 00000000 SECT38 notype       Static       | .rdata

    Section length    D, #relocs    0, #linenums    0, checksum 37DE352B, selection    2 (pick any)
0B3 00000000 SECT38 notype       External     | ??_C@_0N@MHFFIMFG@?6Address?3?50x?$AA@ (`string')

0B4 00000000 SECT39 notype       Static       | .rdata
    Section length   48, #relocs    0, #linenums    0, checksum DB7219C5, selection    2 (pick any)

0B6 00000000 SECT39 notype       External     | ??_C@_0EI@CLEPFNGI@Stack?5area?5around?5_alloca?5memory@ (`string')
0B7 00000000 SECT3A notype       Static       | .rdata

    Section length   1A, #relocs    0, #linenums    0, checksum B3C0476C, selection    2 (pick any)
0B9 00000000 SECT3A notype       External     | ??_C@_0BK@ODNDAGKB@?$CFs?$CFs?$CFp?$CFs?$CFzd?$CFs?$CFd?$CFs?$CFs?$CFs?$CFs?$CFs?$AA@ (`string')

0BA 00000000 SECT3B notype       Static       | .rdata
    Section length   34, #relocs    0, #linenums    0, checksum D4450C50, selection    2 (pick any)
0BC 00000000 SECT3B notype       External     | ??_C@_0DE@OHJBPMBP@A?5variable?5is?5being?5used?5without@ (`string')

0BD 00000000 UNDEF  notype       External     | ___security_cookie
0BE 00000000 SECT3C notype       Static       | .sxdata


...(생략)


  Summary


           4 .00cfg
           4 .CRT$XCA
          10 .CRT$XCAA
           4 .CRT$XCZ
           4 .CRT$XDA
           4 .CRT$XDZ
           4 .CRT$XIA
          10 .CRT$XIAA
          10 .CRT$XIAC
           8 .CRT$XIC
           4 .CRT$XIZ
           4 .CRT$XLA
           4 .CRT$XLC
           4 .CRT$XLD
           4 .CRT$XLZ
           4 .CRT$XPA
           4 .CRT$XPZ
           4 .CRT$XTA
           4 .CRT$XTZ
         3A9 .bss
          38 .data
          77 .data$r
         1D0 .debug$F
       A7880 .debug$S
        3454 .debug$T
         5BF .drectve
          AC .gfids$y
        742E .rdata
          18 .rdata$T
         120 .rdata$r
           4 .rtc$IAA
           4 .rtc$IZZ
           4 .rtc$TAA
           4 .rtc$TZZ
          3C .sxdata
       1B0E8 .text$mn
           F .text$mn$00
          1B .text$x
           1 .tls
          8C .tls$
           1 .tls$ZZZ
         2E0 .xdata$x
       6C630 _RDATA


0BC 00000000 SECT3B notype       External     | ??_C@_0DE@OHJBPMBP@A?5variable?5is?5being?5used?5without@ (`string')

위와 같이 External 이 표기된 부분을 디버그와 릴리즈 모드를 비교해봤더니 릴리즈 모드에서 링크에러가 발생한 symbol을 찾을 수 없었다.

문제가 생긴 함수는 constructor 였는데 명시적으로 구현을 안해서 그런건지 릴리즈에서만 링크 에러가 발생한 것이었다. 다행히 명시적으로 cpp 파일에 구현해주니 링크 에러는 해결되었다.

참고 : https://stackoverflow.com/questions/305287/how-to-see-the-contents-of-windows-library-lib

728x90

이펙트 파티클을 일정 기간 생성된 상태로 초기화하고 싶을 때 Warmup Time 을 설정하게 된다.

UParticleSystemComponent::ActivateSystem 코드를 보면 어떻게 동작하는지 알 수 있는데  WarmupTime을 WarmupTickRate 나눈 수만큼 TickComponent 를 호출하는 식이다.

if (WarmupTime != 0.0f)
{
bool bSaveSkipUpdate = bSkipUpdateDynamicDataDuringTick;
bSkipUpdateDynamicDataDuringTick = true;
bWarmingUp = true;
ResetBurstLists();


float WarmupElapsed = 0.f;
float WarmupTimestep = 0.032f;

if (WarmupTickRate > 0)
{
WarmupTimestep = (WarmupTickRate <= WarmupTime) ? WarmupTickRate : WarmupTime;
}

while (WarmupElapsed < WarmupTime)
{
TickComponent(WarmupTimestep, LEVELTICK_All, NULL);
WarmupElapsed += WarmupTimestep;
}

bWarmingUp = false;
WarmupTime = 0.0f;
}

예를 들어 WarmupTime 을 100 WarmupTickRate 를 0 으로 설정한 경우 100 / 0.032(WarmupTickRate 기본값) = 3125 Tick 을 돌아서 이 이펙트가 스폰될 때 마다 i7 + Nvidia 970 + 32GB Mem 정도 사양에서도 버벅이는 것을 느낄 수 있다. 초당 0.7 정도의 8개 짜리 스프라이트 이펙트였는데 스프라이트 파티클 개수가 10000개에 육박한 것을 볼 수 있었다. :(

728x90

언리얼에서 스크린샷이나 다른 이유로 랙이 걸릴 때 마다 다른 PC 에 비해 World::TimeSeconds 가 느리게 가는 현상이 발견되었다.

확인해보니 AWorldSettings::FixupDeltaSeconds 에 의해 제한되고 있었다.

float AWorldSettings::FixupDeltaSeconds(float DeltaSeconds, float RealDeltaSeconds)

{

// DeltaSeconds is assumed to be fully dilated at this time, so we will dilate the clamp range as well

float const Dilation = GetEffectiveTimeDilation();

float const MinFrameTime = MinUndilatedFrameTime * Dilation;

float const MaxFrameTime = MaxUndilatedFrameTime * Dilation;


// clamp frame time according to desired limits

return FMath::Clamp(DeltaSeconds, MinFrameTime, MaxFrameTime);

}

WorldSettings 의 MinUndilatedFrameTime 과 MaxUndilatedFrameTime 에 설정할 수 있었다.


기본 값은 BaseGame.ini 에 설정되어 있다.

[/Script/Engine.WorldSettings]

MinUndilatedFrameTime=0.0005 ; 2000 fps

MaxUndilatedFrameTime=0.4 ; 2.5 fps

0.4초 이상은 버려지니 스크린샷으로 2~3초가 지났어도 World 는 0.4초 밖에 안 지난 것으로 취급되는 상황이었다.

P2P 마스터를 지원하는 상황에서는 DefaultGame.ini 에 MaxUndilatedFrameTime 을 충분히 큰 값으로 올려주고 그 값을 넘어가는 오차가 발생하면 자르거나 재동기화하는 식으로 구현하는게 좋을 것 같다.

728x90

UE4 에서 C++ Project 를 만들면 프로젝트 이름으로 실행파일명이 생성된다.

uproject 이름 변경하는 법

http://www.worldofleveldesign.com/categories/ue4/ue4-renaming-your-project.php

1. uproject 파일명을 바꾼다.
2. Config/DefaultEngine.ini 에 아래 섹션을 추가/수정한다.

[URL]
GameName=NewName

패키징을 해보니 GameName은 바뀌었으나 실행 파일명은 바뀌지 않았다.
그리고 에디터에서 컴파일하면 오류도 발생하고 svn commit 시에 ensure도 발생했다.

https://answers.unrealengine.com/questions/242407/renaming-a-c-project.html

제대로 바꾸려면 Target.cs, Build.cs 도 바꿔주고 Config 에서 추가 작업도 필요한 것 같다.

회사분이 에디터 컴파일 오류 수정하시다가 Rename.Target.cs 을 NameName.Target.cs 로 이름을 변경하셨다. 그런데 exe 이름도 같이 변경되었다. 실행 파일명은 메인 모듈의 TargetName 을 따라가도록 되어 있나 보다.

P.S. Test 라고 프로젝트 명을 지으면 패키징에서 오류가 발생한다. ;

728x90
언리얼 기본 XML Parser 가 제한 사항이 많아 불편했다.

: attribute 에 "(double quote)를 쓸 수 없다.
: attribute 선언 시에 공백을 쓸 수 없다.
: root element가 value와 child가 없는 element 일 수 없다.


기존에 사용 중인 xml 파일을 그대로 사용하려다 보니 파일마다 고치기 힘들어 다른 XMl Parser 를 가져다 붙였다. 전에는 MS XML Parser 를 썼었는데 언리얼에 붙이기에는 Platform 의존도가 너무 높아지는 것 같아서 TinyXML-2 를 가져다 붙였다.

TinyXML-1 이 메모리 사용이 비효율적이고 모바일 환경에 맞지 않는 것 같아서 TinyXML-2 를 만들었다고 한다.

TinyXML-1 과 TinyXML-2 장단점을 비교한 것도 있다.

Both parsers:

  1. Simple to use with similar APIs.
  2. DOM based parser.
  3. UTF-8 Unicode support. http://en.wikipedia.org/wiki/UTF-8

Advantages of TinyXML-2

  1. The focus of all future dev.
  2. Many fewer memory allocation (1/10th to 1/100th), uses less memory (about 40% of TinyXML-1), and faster (~5x on read).
  3. No STL requirement.
  4. More modern C++, including a proper namespace.
  5. Proper and useful handling of whitespace

Advantages of TinyXML-1

  1. Can report the location of parsing errors.
  2. Support for some C++ STL conventions: streams and strings
  3. Very mature and well debugged code base.

ReleaseDll 정적 라이브러리를 만들어서 언리얼에 붙였다.

붙이고 테스트 해보니 몇 가지 문제점이 있었다.

: utf-8 을 지원한다고는 하지만 LoadFile 은 fopen 을 사용하고 있는 관계로 ANSI 문자열만 지원한다. . 파일명이 다른 국가 문자열을 포함한다면 읽어들일 수 없었다.
: utf-16 을 지원하지 않는다.

그래서 다음과 같은 방식으로 wrap 해서 사용하고 있다.

: 언리얼은 다국어를 지원하는 관계로 FileHelper::LoadFileToString 을 이용하여 다국어 파일명의 파일을 읽어들인다.
: TinyXML2 로 보내기 위해 utf-8 으로 문자열을 변환한다.
: XmlDocument::Parse 를 통해 파싱 후 각 element 의 문자열 데이터를 UTF8_TO_TCHAR 를 이용하여 변환해서 사용한다.

공식 홈페이지 : http://www.grinninglizard.com/tinyxml2/


728x90

Git 저장소를 export 해서 전달해야할 때는 git archive 를 사용하면 된다.


현재 브랜치의 가장 최신 내용을 export 하는 경우


git archive --format=tar --prefix=junk/ HEAD



zip 으로 remote 브랜치를 export 하는 경우


git archive --format=zip branch.zip remotes/origin/branch





참고 : https://git-scm.com/docs/git-archive

728x90

윈도우 명령줄(cmd.exe) 에서 for 루프 내에서 문자열을 set 으로 붙이려고 했으나 동작하지 않고 %XX% 가 미리 처리되어 마지막 set 만 처리되었다.

 

[코드]

 

for /f %%a ('dir /a /b') do set XX=%XX% %%a 

 

[실제 동작]

 

for /f %%a ('dir /a /b') do set XX= %%a

 

검색해보니 Delayed Expansion 을 enable 해서 처리하거나 goto 문을 이용하는 방법이 있었다. Delayed Expansion 을 enable 하는 것이 더 깔끔한 것 같다.

 

@echo off
setlocal enabledelayedexpansion
set myvar=the list:
for /r %%i In (*.sql) DO set myvar=!myvar! %%i,
echo %myvar%

 

출처 : http://stackoverflow.com/questions/2027070/how-to-concatenate-strings-in-a-windows-batch-file

728x90

UE4 로 작업할 때 IncrediBuild 가 설치되어 있어도 쓰고 싶지 않은 경우가 있다. IncrediBuild agent 를 disable 하면 서버 접속할 수 없다는 오류가 뜬다. 


다음과 같이 BuildConfiguration.xml 을 설정하면 된다.

경로는 %appData%\Unreal Engine\UnrealBuildTool\BuildConfiguration.xml 이 최우선인 것 같다.


<?xml version="1.0" encoding="utf-8" ?><Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">

<BuildConfiguration>

<bAllowXGE>false</bAllowXGE>

</BuildConfiguration>

</Configuration>



출처 : https://answers.unrealengine.com/questions/488246/how-to-disable-incredibuild.html

728x90

Visual Studio 2015 로 전환 중인데 hash_map 이 deprecate 처리되어 있어 당황했다. unordered_map 을 쓰는게 맞는데 코드를 전부 바꾸려니 귀찮았다. unordered_map 을 hash_map 이라는 이름으로 쓰고 싶어서 찾아보니 C++ 11 에 alias template 이라는 방법 있었다.

 

// type alias used to hide a template parameter
template<class CharT>
using mystring = std::basic_string<CharT, std::char_traits<CharT>>;
mystring<char> str;

 

 

출처 : http://en.cppreference.com/w/cpp/language/type_alias

728x90

자체 lib 를 사용하는 플러그인 형태의 코드를 사용하고 있는데 Win32 빌드를 했다. 마른 하늘에 날벼락같은 C1905 오류로 링크가 실패했다.


심각한 오류 C1905


프런트 엔드와 백 엔드가 호환되지 않습니다. 같은 프로세서를 대상으로 해야 합니다.


출처 : https://msdn.microsoft.com/ko-kr/library/414e6214.aspx


컴파일러에 의해 생성된 obj 파일의 x86, ARM, x64 와 같은 타겟 머신이 다를 경우에 발생하는 오류다. dumpbin 으로 확인해봤으나 사용하는 lib 파일들은 다 x86 이었다.


한동안 해결을 못하고 막혀 있다가 혹시나 싶어 옵션들을 확인해봤다. lib 파일의 전체 프로그램 최적화 옵션을 '링크 타임 코드 생성 사용'에서 '전체 프로그램 최적화 안 함'으로 바꿨더니 문제가 사라졌다.


x64 버전은 '링크 타임 코드 생성 사용' 옵션으로 해도 문제가 발생하지 않았다.


lib 파일을 '링크 타임 코드 생성 사용'으로 하고 자체 제작한 테스트용 exe 파일을 '전체 프로그램 최적화 안 함'이나 다른 옵션으로 바꿔도 문제가 발생하지 않았다.


UE4 빌드시에 어떤 옵션이 충돌하지는 모르겠으나 링크 시 C1905 오류가 발생한다면 자체 제작한 lib 의 전체 프로그램 최적화 옵션을 '전체 프로그램 최적화 안 함'으로 바꾸고 시도해 보길 바란다.


728x90

+ Recent posts