[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계

Sungkyun Kim
Sungkyun KimTechnical Director at Innospark em INNOSPARK Inc.
두 마리 토끼를 잡기 위한 
C++ - C# 혼합 멀티플랫폼 
게임 아키텍처 설계 
㈜이노스파크 
Technical Director 
김성균
목차 
1. 개요 
2. C# (.NET) 실행환경 
3. 언어 간 인터페이스 결합 자동화 
4. 언어 간 개체 결합 
5. 결론 
6. 부록
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계
동기 
 빠른 성능 
 구현의 자유성 
 높은 이식성 
− 코딩의 실수는 치명적 
− 낮은 생산성 
 높은 생산성 (문법, OOP …) 
 적절한 성능 
 C++와 유사한 문법 
− 저수준 제어 어려움 
− 다른 환경과 연동 어려움
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계
목표 
언어간 코드 연동을 위한 작업량 최소화 
코드를 다른 언어로 손쉽게 변환 
• 성능이 중요한 기능 
• 저수준 제어 
• 외부 라이브러리 연동 
• 빠른 구현과 잦은 변경이 필 
요한 상위 수준의 기능들 
• 성능이 중요하지 않은 코드
[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C#  혼합 멀티플랫폼 게임 아키텍처 설계
Native 
Code 
Script 
Lib
구성 요소 
C# 런타임 
언어 간 인터페이 
스 자동화 
언어 간 개체 결합
C# (.NET) 실행환경
Mono™ = Microsoft .NET의 포팅 
≈ 오픈소스, 공짜 아님
각 플랫폼용 Mono 빌드 
소스코드 
mono 
Runtime 
(.a .so .lib .dll) 
make 
make 
configure 
Compiler
App 
Embedded Mono 
Native Runtime 
.NET Assembly 
로드 & JIT 컴파일 
컴 
파 
일 
JIT / AOT Binary 
Mono Runtime 
실행 
.NET Compiler 
Objective-C 
Runtime 
Java VM
임베딩을 위한 C# 코드 처리 
.NET Compiler 
monolinker 
mono 
Reduced Assembly 
.NET Assembly 
Stripped Assembly 
mov … 
push … 
call … 
Assembly Code 
.NET Libraries 
AOT 컴파일
Embedded Mono 유의사항 
Ahead-of-Time 컴파일 
– Just-in-Time 실행을 지원하지 않는 OS를 위함 
– 실행될 CPU/OS 마다 별도의 Mono 컴파일러와 런타임 필요 
– 실행파일 크기 문제 
– 리소스 업데이트로 C# 코드 업데이트 불가능 
디버깅 
– Custom Command Soft Debugger 사용 필요 
– 디버깅 대상이 client, MonoDevelop이 server로 작동 
– 쓰레드에서 Mono 코드를 실행하지 않으면 중단점 작동 안됨 
sgen GC 사용시 MonoObject* 대신 gc_handle 에 의존 
mono_trace_set_level_string 사용 추천
언어 간 인터페이스 결합 자동화
목표: 언어간 혼용의 자유도 
class Character 
{ 
void SetPosition( float ); 
float position; 
}; 
class Character 
{ 
void Touched() … 
void UpdateUI() … 
int health; 
}
목표: 언어간 혼용의 자유도 
void Character::Touched() 
{ 
SetPosition( position + 1 ); 
} 
class Character 
{ 
void SetPosition( float ); 
float position; 
};
목표: 언어간 혼용의 자유도 
void Character::SetPosition( float position ) 
{ 
… 
health = … 
UpdateUI(); 
} 
class Character 
{ 
void Touched() … 
void UpdateUI() … 
int health; 
}
목표: 언어간 혼용의 자유도 
• 구현의 특성에 가장 적합한 언어에서 코딩 
• C# 모듈을 C++ 처럼, C++ 모듈을 C# 처럼 사용 
• 인터페이스용 코드 필요 
– 각 타입에 대한 메타정보 등록 코드 
– 호출 언어를 위해 정의된 선언(declaration) 코드 
• 언어 간 인터페이스를 자동화 한다면?!
언어간 인터페이스 자동생성 
C++ 소 
스코드 
(.h) 
C# 소스 
코드 
C++ 인 
터페이스 
C# 코드 
C# 인터 
페이스 
C++ 코 
드 
2 
3 
4 
1 
CppSharp 
CXXI 
…
C#을 위한 C++ 인터페이스 자동생성 
CppSharp 
CXXI 
+ Clang 
1. C++ 헤더파일들을 파싱(!)하여 인터페이스들 분석 
2. (C++ 인터페이스를 Mono에 노출하는 C++ 코드)와 
이를 호출할 수 있는 C# 코드 생성 
3. C# 코드에서 인터페이스 코드를 호출 
4. C# 코드 컴파일시 인터페이스 코드를 함께 컴파일
C++ 파싱 - Clang 
 LLVM 컴파일러의 C/C++ 파서 
 상용 제품 수준 
 Visual C++ 구문들도 인식 
 불완전한 구문에 의해 파싱이 실패하지 않음 
 libclang을 이용하여 스크립트 언어에서도 사용 가능, 
Python 모듈 기본 제공 – AST 생성 
− libclang은 clang의 극히 일부의 기능만을 노출하므 
로 커스터마이제이션 필요
C++ 인터페이스 생성 예제 (CppSharp) 
// C++ 소스코드 
class Foo 
{ 
int variable; 
int DoSomething ( int arg1, std::string arg2 ); 
}; 
// 자동 생성된 C#용 인터페이스 코드 
class Foo 
{ 
// C++의 메모리 레이아웃 선언 
struct Internal { … } 
// 사용자를 위한 편리한 인터페이스 
int variable { 
get { return _Instance.ToPointer()->variable; } 
set { _Instance.ToPointer()->variable = value; } 
} 
int DoSomething( int arg1, string arg2 ) 
{ return Internal.DoSomething( _Instance, arg1, arg2 ); } 
}
C++ 인터페이스 생성 예제 (Embedded) 
// C++ 소스코드 
#define EXPORT __attribute__((annotate(“ExportToMono”))) 
class EXPORT Foo 
{ 
int variable; 
int DoSomething ( int arg1, std::string arg2 ); 
}; 
+ Clang 
// 자동 생성된 클래스 등록 코드 
RegisterNativeClass<Foo>(); 
RegisterNativeClassVariable<Foo,int>( “variable”, offsetof(Foo, variable) ); 
RegisterNativeClassMethod<Foo,int,int,std::string>( “DoSomething”, &Foo::DoSomething );
C++ 인터페이스 생성 예제 (Embedded) 
// 자동 생성된 클래스 등록 코드에 의한 실제 내부 작동 
RegisterNativeClass<Foo>(); 
// Foo 타입에 대한 RTTI등 각종 기본 정보들 등록 
RegisterNativeClassVariable<Foo,int>( “variable”, offsetof(Foo, variable) ); 
// C#에서 호출할 accessor 메소드 등록 
int NativeGetInt( void* nativeObject, int offset ); 
mono_add_internal_call( “NativeGetInt”, &NativeGetInt ); 
void NativeSetInt( void* nativeObject, int offset, int value ); 
mono_add_internal_call( “NativeSetInt”, &NativeSetInt ); 
RegisterNativeClassMethod<Foo,int,int,std::string>( “DoSomething”, &Foo::DoSomething ); 
// C#에서 호출할 메소드 등록 
static int Foo_DoSomething( Foo* nativeObject, int arg1, std::string arg2 ) 
{ nativeObject->DoSomething( arg1, arg2 ); } 
mono_add_internal_call( “Foo.NativeCall_DoSomething”, &Foo_DoSomething );
C++ 인터페이스 생성 예제 (Embedded) 
// 자동 생성된 C#용 인터페이스 코드 
class Foo 
{ 
// C++의 메소드들 등록 
[MethodImplAttribute(MethodImplOptions.InternalCall)] 
extern int NativeCall_DoSomething( IntPtr nativeObject, int arg1, string arg2 ); 
// 사용자를 위한 편리한 인터페이스 
int variable { 
get { return NativeGetInt( nativeObject, 4 ); } 
set { NativeSetInt( nativeObject, 4 ); } 
} 
int DoSomething( int arg1, string arg2 ) 
{ return NativeCall_DoSomething( nativeObject, arg1, arg2 ); } 
}
C++를 위한 C# 인터페이스 자동생성 
1. .NET reflection을 사용하여 DLL 안의 인터페이스 
들 추적 
2. DLL 인터페이스를 호출할 수 있는 C++ 코드 생성 
3. C++ 게임코드에서 인터페이스 코드를 통해 DLL의 
코드를 C++ 처럼 호출 
4. C++ 게임코드 컴파일시 인터페이스 코드를 함께 
컴파일
C# 인터페이스 생성 예제 (Delegate) 
// 자동 생성된 C# 인터페이스 코드 
partial class Foo 
{ 
void ExposeToNative() { 
RegisterMonoMethod( 0, () => { return variable; } ); // Get_variable 
RegisterMonoMethod( 1, (int value) => { variable = value; } ); // Set_variable 
RegisterMonoMethod( 2, DoSomething ); // DoSomething 
} 
} 
// 자동 생성된 C++ 인터페이스 코드 
class Foo 
{ 
int Get_variable() { monoMethods[0](); } 
void Set_variable( int value ) { return monoMethods[1]( value ); } 
int DoSomething( int arg1, std::string arg2 ) 
{ return monoMethods[2]( arg1, arg2 ); } 
}; 
delegate를 native 함수 포인터로 전달 
RegisterMonoMethod에 의해 등록된 함수 포인터
C# 인터페이스 생성 예제 (Embedded) 
// C# 소스코드 
[Export] 
class Foo 
{ 
// 자동 생성된 C++용 인터페이스 코드 
class Foo 
{ 
int variable; 
int DoSomething( int arg1, string arg2 ) { … } 
} 
int Get_variable() { 
void* ret = mono_runtime_invoke( monoClass, monoObject, “get_variable” ); 
return *(int*)ret; 
} 
void Set_variable( int value ) { 
mono_runtime_invoke( monoClass, monoObject, “set_variable”, [&value] ); 
} 
int DoSomething( int arg1, std::string arg2 ) { 
void* ret = mono_runtime_invoke( monoClass, monoObject, “DoSomething”, 
[&arg1, mono_string_new_wrapper(arg2)] ); 
return *(int*)ret; 
} 
};
언어 간 개체 결합
언어 간 결합의 깊이 
모듈 간 결합 다른 객체 간 결합 객체 수준 결합 
C++ Class 
C++ variables 
C++ methods 
C# Class 
C# variables 
C# methods 
Hybrid Class 
C++ variables 
C# variables 
C++ methods 
C# methods 
오브젝트 참조 
클래스 형 변환 
C++ 기능 모듈 
표준 호출 
단순 타입 
C# 기능 모듈 
개체 생명주기 관리
객체 수준 결합 
단일 메모리의 구역 분할 
• C# 클래스 선언에서 C++ 클래스의 
영역 미리 선언 필요 
• 개체의 수명은 C#에 의해서만 관 
리되어야 함 
• C++ new/delete 사용 불가
객체 수준 결합 
개체 분할, 논리적 결합 
• 독립적인 C++개체와 C#개체 
• 필요할 때에만 상대개체 생성 가 
능 
• 자동생성된 소스코드 빌드에 유리 
(partial class) 
• 개체 수명관리가 핵심
Garbage Collection vs new/delete 
C++ 개체가 소유자 
mono_gchandle_new 
mono_gchandle_free 
C# 개체가 소유자 상호 참조 
new / delete 
gchandle refcount
상대 개체 동적생성 예제 
// 자동생성된 C++용 인터페이스 코드 
class FooProxy 
{ 
FooProxy( Foo* nativeObject ) 
{ // C#측의 Foo 개체가 없으면 생성 } 
int DoInCS( int arg ) 
{ // C#측의 Foo.DoInCS 호출 } 
}; 
// C# 소스코드 
class Foo : public NativeBound 
{ 
int DoInCS( int arg ) { … } 
} 
// C++ 소스코드 
class Foo : public MonoBound 
{ 
int DoInCPP( int arg ) 
{ 
return FooProxy(this).DoInCS(arg); 
} 
}; 
성능 주의
삭제 - Garbage Collector 연동 
살아있는 쌍 GC 활성화 Native 삭제 
GC handle 
3 1 
Mono GC에 의 
해 제거 가능 
Mono GC에 의 
해 제거 방지 
Mono 
GC 
Native 
GC 
0 
Mono GC에 의해 
제거됨 
삭제됨 
참조 카운트 
GC handle 삭제
최종 형태 
Data Engine 
부분 최적화 
과거의 
게임코드
결론 
Roslyn 
.NET Native, IL2CPP 
CppSharp, Script# 
거의 모든 플랫폼에서 .NET과 C# 사용 가능 
언어간 혼합의 자동화 → 더욱 높은 생산성과 이식성 
.NET과 C#은 여전히 진화중
Q&A 
감사합니다
부록
참고자료 
.NET 
– Reflection: http://msdn.microsoft.com/en-us/library/f7ykdhsy(v=vs.110).aspx 
– Garbage Collection: http://msdn.microsoft.com/en-us/library/0xy59wtx(v=vs.110).aspx 
Mono 
– http://www.mono-project.com 
– Compiling Mono: http://www.mono-project.com/docs/compiling-mono/compiling-from-git/ 
– Embedding Mono: http://www.mono-project.com/docs/advanced/embedding/ 
– InterOp with Native: http://www.mono-project.com/docs/advanced/pinvoke/ 
– CppSharp: https://github.com/mono/CppSharp 
– CXXI: http://tirania.org/blog/archive/2011/Dec-19.html 
– Mono for Unreal Engine: http://mono-ue.github.io/ 
Clang 
– http://clang.llvm.org 
– Python with Clang: http://eli.thegreenplace.net/2011/07/03/parsing-c-in-python-with-clang
iOS 시뮬레이터용 Mono 런타임 configure 
• --build=i386-apple-darwin13.0.0 
• CC, CXX=<Xcode 
configure 
path>/Contents/Developer/Platforms/iPhoneSimulator.p 
latform/Developer/usr/bin 안의 gcc와 g++ 
• CFLAGS, CXXFLAGS 
– -arch i386 –miphoneos-version-min=<최소지원버전> 
– -isysroot=<Xcode 
path>/Contents/Developer/Platforms/iPhoneSimulator.platform/Deve 
loper/SDKs/iPhoneSimulator<버전>.sdk 
• LD, AS, AR, LIBTOOL, STRIP, 
RANLIB=<iPhoneSimulator SDK>/usr/bin 안에 있는 툴들 
사용
iOS 기기용 Mono 런타임 configure 
• --host=arm-apple-darwin10 
• --target=arm-apple-darwin10 
• CC, CXX=<Xcode 
Mono 3.2의 경우 XCode 4.x를 configure 
사용해야 함 
path>/Contents/Developer/Toolchains/XcodeDefault.xctoolc 
hain/usr/bin 안의 clang과 clang++ 
• CFLAGS, CXXFLAGS 
– -arch armv7 
– -isysroot=<Xcode 
path>/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SD 
Ks/iPhoneOS???.sdk 
• LD, AS, AR, LIBTOOL, STRIP, RANLIB=<Xcode 
path>/Contents/Developer/Platforms/iPhoneOS.platform/Dev 
eloper/usr/bin 안에 있는 툴들 사용
Android 기기용 Mono 런타임 configure 
• --host=arm-linux-androideabi 
• --target=arm-linux-androideabi 
• CC, CXX=<Xcode 
path>/Contents/Developer/Toolchains/XcodeDefault.xctoolc 
hain/usr/bin 안의 clang과 clang++ 
• CFLAGS, CXXFLAGS 
– -march=armv7-a 
– -mfloat-abi=softfp 
– -mfpu=neon 
– --sysroot=<NDK_ROOT>/platforms/android-<version>/arch-arm 
• LD, AS, AR, LIBTOOL, STRIP, RANLIB 설정 불필요 
• --libdir <NDK_ROOT>/platforms/android-<version>/arch-arm/ 
usr/lib 
configure
C++ → Lua 예제 
// 자동 생성된 클래스 등록 코드에 의한 실제 내부 작동 
RegisterNativeClass<Foo>(); 
// 클래스를 lua table로 생성 
lua_createtable( “Foo” ); 
RegisterNativeClassVariable<Foo,int>( “variable”, offsetof(Foo, variable) ); 
// lua table에 getter/setter 멤버 함수들 등록 
lua_pushcclosure( “Get_variable”, &NativeGetInt ); 
lua_pushcclosure( “Set_variable”, &NativeSetInt ); 
RegisterNativeClassMethod<Foo,int,int,std::string>( “DoSomething”, &Foo::DoSomething ); 
// lua table에 멤버 함수 호출자 등록 
lua_pushcclosure( “DoSomething”, &Foo_DoSomething ); 
// 자동 생성된 lua용 인터페이스 코드 - 주석 또는 Lua Checker 용도 외에는 필요 없음 
Foo = { 
Get_variable = function(), 
Set_variable = function( int_value ), 
DoSomething = function( int_arg1, string_arg2 ) 
} 
명시적 accessor 대신 __index, 
__newindex로 구현 가능
Lua → C++ 예제 
// lua 소스코드 
Foo = { 
variable = 0, 
int_DoSomething = function( int_arg1, string_arg2 ) 
… 
end 
// 자동 생성된 C++용 인터페이스 코드 
} 
class Foo 
{ 
int Get_variable() { return lua_tointeger( “variable” ); } 
void Set_variable( int value ) { lua_pushinteger( “variable”, value ); } 
int DoSomething( int arg1, std::string arg2 ) 
{ 
lua_pushinteger( arg1 ); 
lua_pushstring( arg2 ); 
lua_pcall( “DoSomething” ); 
return lua_tointeger( STACK_TOP ); 
} 
};
1 de 48

Recomendados

양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012 por
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012
양승명, 다음 세대 크로스플랫폼 MMORPG 아키텍처, NDC2012devCAT Studio, NEXON
3.5K visualizações63 slides
How Akamai Made ESI Testing Simpler por
How Akamai Made ESI Testing SimplerHow Akamai Made ESI Testing Simpler
How Akamai Made ESI Testing SimplerAkamai Developers & Admins
1.3K visualizações17 slides
인프런 - 스타트업 인프랩 시작 사례 por
인프런 - 스타트업 인프랩 시작 사례인프런 - 스타트업 인프랩 시작 사례
인프런 - 스타트업 인프랩 시작 사례Hyung Lee
30.2K visualizações33 slides
독립 개발 4년차 리뷰 por
독립 개발 4년차 리뷰독립 개발 4년차 리뷰
독립 개발 4년차 리뷰Daehoon Han
2.5K visualizações149 slides
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012 por
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012devCAT Studio, NEXON
6.9K visualizações72 slides
NDC12_Lockless게임서버설계와구현 por
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현noerror
7.7K visualizações48 slides

Mais conteúdo relacionado

Mais procurados

Python 게임서버 안녕하십니까 : RPC framework 편 por
Python 게임서버 안녕하십니까 : RPC framework 편Python 게임서버 안녕하십니까 : RPC framework 편
Python 게임서버 안녕하십니까 : RPC framework 편준철 박
7.4K visualizações78 slides
게임프로젝트에 적용하는 GPGPU por
게임프로젝트에 적용하는 GPGPU게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPUYEONG-CHEON YOU
5.4K visualizações51 slides
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기 por
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기현철 조
10.7K visualizações63 slides
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기 por
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기강 민우
5.1K visualizações75 slides
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017 por
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017devCAT Studio, NEXON
3.7K visualizações50 slides
송창규, unity build로 빌드타임 반토막내기, NDC2010 por
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010devCAT Studio, NEXON
32.1K visualizações72 slides

Mais procurados(20)

Python 게임서버 안녕하십니까 : RPC framework 편 por 준철 박
Python 게임서버 안녕하십니까 : RPC framework 편Python 게임서버 안녕하십니까 : RPC framework 편
Python 게임서버 안녕하십니까 : RPC framework 편
준철 박7.4K visualizações
게임프로젝트에 적용하는 GPGPU por YEONG-CHEON YOU
게임프로젝트에 적용하는 GPGPU게임프로젝트에 적용하는 GPGPU
게임프로젝트에 적용하는 GPGPU
YEONG-CHEON YOU5.4K visualizações
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기 por 현철 조
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
[NDC17] Unreal.js - 자바스크립트로 쉽고 빠른 UE4 개발하기
현철 조10.7K visualizações
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기 por 강 민우
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
강 민우5.1K visualizações
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017 por devCAT Studio, NEXON
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017
이승재, 일정대로 출시하기 왜 & 어떻게: 개발자를 위한 제작진행개론, NDC2017
devCAT Studio, NEXON3.7K visualizações
송창규, unity build로 빌드타임 반토막내기, NDC2010 por devCAT Studio, NEXON
송창규, unity build로 빌드타임 반토막내기, NDC2010송창규, unity build로 빌드타임 반토막내기, NDC2010
송창규, unity build로 빌드타임 반토막내기, NDC2010
devCAT Studio, NEXON32.1K visualizações
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오... por Amazon Web Services Korea
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
Amazon Web Services Korea4.4K visualizações
이원, 온라인 게임 프로젝트 개발 결산 - 마비노기 개발 완수 보고서, NDC2011 por devCAT Studio, NEXON
이원, 온라인 게임 프로젝트 개발 결산 - 마비노기 개발 완수 보고서, NDC2011이원, 온라인 게임 프로젝트 개발 결산 - 마비노기 개발 완수 보고서, NDC2011
이원, 온라인 게임 프로젝트 개발 결산 - 마비노기 개발 완수 보고서, NDC2011
devCAT Studio, NEXON5K visualizações
アプリ開発者が動画広告を導入するときに気にすべきいくつかのこと por Yasuyuki Kamata
アプリ開発者が動画広告を導入するときに気にすべきいくつかのことアプリ開発者が動画広告を導入するときに気にすべきいくつかのこと
アプリ開発者が動画広告を導入するときに気にすべきいくつかのこと
Yasuyuki Kamata8.8K visualizações
게임기획 포트폴리오 애니팡역기획 배상욱 por SwooBae
게임기획 포트폴리오 애니팡역기획 배상욱게임기획 포트폴리오 애니팡역기획 배상욱
게임기획 포트폴리오 애니팡역기획 배상욱
SwooBae45.2K visualizações
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지) por 내훈 정
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이  왜 이리 힘드나요?  (Lock-free에서 Transactional Memory까지)
Ndc2014 시즌 2 : 멀티쓰레드 프로그래밍이 왜 이리 힘드나요? (Lock-free에서 Transactional Memory까지)
내훈 정28.9K visualizações
Understanding Stack Overflow por Alexander Serebrenik
Understanding Stack OverflowUnderstanding Stack Overflow
Understanding Stack Overflow
Alexander Serebrenik1.7K visualizações
Deep Exploit@Black Hat Europe 2018 Arsenal por Isao Takaesu
Deep Exploit@Black Hat Europe 2018 ArsenalDeep Exploit@Black Hat Europe 2018 Arsenal
Deep Exploit@Black Hat Europe 2018 Arsenal
Isao Takaesu2.6K visualizações
Windows Registered I/O (RIO) vs IOCP por Seungmo Koo
Windows Registered I/O (RIO) vs IOCPWindows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCP
Seungmo Koo29K visualizações
[NDC2017 정서연] 몬스터 슈퍼리그 리텐션 15% 개선 리포트 - 숫자보다 매력적인 감성 테라피 por Jeong Seoyeon
[NDC2017 정서연] 몬스터 슈퍼리그 리텐션 15% 개선 리포트 - 숫자보다 매력적인 감성 테라피[NDC2017 정서연] 몬스터 슈퍼리그 리텐션 15% 개선 리포트 - 숫자보다 매력적인 감성 테라피
[NDC2017 정서연] 몬스터 슈퍼리그 리텐션 15% 개선 리포트 - 숫자보다 매력적인 감성 테라피
Jeong Seoyeon13K visualizações
Display color와 Digital texture format의 이해 por SangYun Yi
Display color와 Digital texture format의 이해Display color와 Digital texture format의 이해
Display color와 Digital texture format의 이해
SangYun Yi3.7K visualizações
[NDC 2014] 모에론 por Yongha Kim
[NDC 2014] 모에론[NDC 2014] 모에론
[NDC 2014] 모에론
Yongha Kim157.2K visualizações
HoloLens2とMeta QuestではじめるWebXR por Takashi Yoshinaga
HoloLens2とMeta QuestではじめるWebXRHoloLens2とMeta QuestではじめるWebXR
HoloLens2とMeta QuestではじめるWebXR
Takashi Yoshinaga1.1K visualizações
NDC 2010 이은석 - 마비노기 영웅전 포스트모템 1부 por Eunseok Yi
NDC 2010 이은석 - 마비노기 영웅전 포스트모템 1부NDC 2010 이은석 - 마비노기 영웅전 포스트모템 1부
NDC 2010 이은석 - 마비노기 영웅전 포스트모템 1부
Eunseok Yi8.7K visualizações
코루틴(Coroutine) por QooJuice
코루틴(Coroutine)코루틴(Coroutine)
코루틴(Coroutine)
QooJuice2.6K visualizações

Similar a [KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계

NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기 por
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기Jaeseung Ha
4.8K visualizações100 slides
Google Protocol buffer por
Google Protocol bufferGoogle Protocol buffer
Google Protocol bufferknight1128
12.9K visualizações40 slides
20201121 코드 삼분지계 por
20201121 코드 삼분지계20201121 코드 삼분지계
20201121 코드 삼분지계Chiwon Song
138 visualizações20 slides
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호) por
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)Sang Don Kim
2.7K visualizações79 slides
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기 por
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기Chris Ohk
6.8K visualizações79 slides
Boost 라이브리와 C++11 por
Boost 라이브리와 C++11Boost 라이브리와 C++11
Boost 라이브리와 C++11OnGameServer
56.7K visualizações61 slides

Similar a [KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계(20)

NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기 por Jaeseung Ha
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
Jaeseung Ha4.8K visualizações
Google Protocol buffer por knight1128
Google Protocol bufferGoogle Protocol buffer
Google Protocol buffer
knight112812.9K visualizações
20201121 코드 삼분지계 por Chiwon Song
20201121 코드 삼분지계20201121 코드 삼분지계
20201121 코드 삼분지계
Chiwon Song138 visualizações
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호) por Sang Don Kim
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
Sang Don Kim2.7K visualizações
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기 por Chris Ohk
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
Chris Ohk6.8K visualizações
Boost 라이브리와 C++11 por OnGameServer
Boost 라이브리와 C++11Boost 라이브리와 C++11
Boost 라이브리와 C++11
OnGameServer56.7K visualizações
kics2013-winter-biomp-slide-20130127-1340 por Samsung Electronics
kics2013-winter-biomp-slide-20130127-1340kics2013-winter-biomp-slide-20130127-1340
kics2013-winter-biomp-slide-20130127-1340
Samsung Electronics106 visualizações
Hoons 닷넷 정기세미나 por 병걸 윤
Hoons 닷넷 정기세미나Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나
병걸 윤794 visualizações
[shaderx6]8.2 3d engine tools with c++cli por 종빈 오
[shaderx6]8.2 3d engine tools with c++cli[shaderx6]8.2 3d engine tools with c++cli
[shaderx6]8.2 3d engine tools with c++cli
종빈 오562 visualizações
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신) por Sang Don Kim
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
Sang Don Kim3.8K visualizações
코드 생성을 사용해 개발 속도 높이기 NDC2011 por Esun Kim
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011
Esun Kim6.3K visualizações
Tech Update - The Future of .NET Framework (김명신 부장) por Eunbee Song
Tech Update - The Future of .NET Framework (김명신 부장)Tech Update - The Future of .NET Framework (김명신 부장)
Tech Update - The Future of .NET Framework (김명신 부장)
Eunbee Song1.9K visualizações
C#을 사용한 빠른 툴 개발 por 흥배 최
C#을 사용한 빠른 툴 개발C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발
흥배 최6.5K visualizações
The Future of .NET and C# por 명신 김
The Future of .NET and C#The Future of .NET and C#
The Future of .NET and C#
명신 김138 visualizações
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic) por Dong Chan Shin
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
Dong Chan Shin2.8K visualizações
Domain Specific Languages With Groovy por Tommy C. Kang
Domain Specific Languages With GroovyDomain Specific Languages With Groovy
Domain Specific Languages With Groovy
Tommy C. Kang1.8K visualizações
Effective c++ chapter1 2_dcshin por Dong Chan Shin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshin
Dong Chan Shin463 visualizações
Tech-days 미니 토요세미나 - 3회 C#편 PPT 자료 por SeongTae Jeong
Tech-days 미니 토요세미나 - 3회 C#편 PPT 자료Tech-days 미니 토요세미나 - 3회 C#편 PPT 자료
Tech-days 미니 토요세미나 - 3회 C#편 PPT 자료
SeongTae Jeong1.6K visualizações
Ch09 por Hankyo
Ch09Ch09
Ch09
Hankyo386 visualizações
프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~ por YEONG-CHEON YOU
프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~
프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~
YEONG-CHEON YOU7.4K visualizações

[KGC2014] 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계

  • 1. 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계 ㈜이노스파크 Technical Director 김성균
  • 2. 목차 1. 개요 2. C# (.NET) 실행환경 3. 언어 간 인터페이스 결합 자동화 4. 언어 간 개체 결합 5. 결론 6. 부록
  • 5. 동기  빠른 성능  구현의 자유성  높은 이식성 − 코딩의 실수는 치명적 − 낮은 생산성  높은 생산성 (문법, OOP …)  적절한 성능  C++와 유사한 문법 − 저수준 제어 어려움 − 다른 환경과 연동 어려움
  • 7. 목표 언어간 코드 연동을 위한 작업량 최소화 코드를 다른 언어로 손쉽게 변환 • 성능이 중요한 기능 • 저수준 제어 • 외부 라이브러리 연동 • 빠른 구현과 잦은 변경이 필 요한 상위 수준의 기능들 • 성능이 중요하지 않은 코드
  • 10. 구성 요소 C# 런타임 언어 간 인터페이 스 자동화 언어 간 개체 결합
  • 12. Mono™ = Microsoft .NET의 포팅 ≈ 오픈소스, 공짜 아님
  • 13. 각 플랫폼용 Mono 빌드 소스코드 mono Runtime (.a .so .lib .dll) make make configure Compiler
  • 14. App Embedded Mono Native Runtime .NET Assembly 로드 & JIT 컴파일 컴 파 일 JIT / AOT Binary Mono Runtime 실행 .NET Compiler Objective-C Runtime Java VM
  • 15. 임베딩을 위한 C# 코드 처리 .NET Compiler monolinker mono Reduced Assembly .NET Assembly Stripped Assembly mov … push … call … Assembly Code .NET Libraries AOT 컴파일
  • 16. Embedded Mono 유의사항 Ahead-of-Time 컴파일 – Just-in-Time 실행을 지원하지 않는 OS를 위함 – 실행될 CPU/OS 마다 별도의 Mono 컴파일러와 런타임 필요 – 실행파일 크기 문제 – 리소스 업데이트로 C# 코드 업데이트 불가능 디버깅 – Custom Command Soft Debugger 사용 필요 – 디버깅 대상이 client, MonoDevelop이 server로 작동 – 쓰레드에서 Mono 코드를 실행하지 않으면 중단점 작동 안됨 sgen GC 사용시 MonoObject* 대신 gc_handle 에 의존 mono_trace_set_level_string 사용 추천
  • 17. 언어 간 인터페이스 결합 자동화
  • 18. 목표: 언어간 혼용의 자유도 class Character { void SetPosition( float ); float position; }; class Character { void Touched() … void UpdateUI() … int health; }
  • 19. 목표: 언어간 혼용의 자유도 void Character::Touched() { SetPosition( position + 1 ); } class Character { void SetPosition( float ); float position; };
  • 20. 목표: 언어간 혼용의 자유도 void Character::SetPosition( float position ) { … health = … UpdateUI(); } class Character { void Touched() … void UpdateUI() … int health; }
  • 21. 목표: 언어간 혼용의 자유도 • 구현의 특성에 가장 적합한 언어에서 코딩 • C# 모듈을 C++ 처럼, C++ 모듈을 C# 처럼 사용 • 인터페이스용 코드 필요 – 각 타입에 대한 메타정보 등록 코드 – 호출 언어를 위해 정의된 선언(declaration) 코드 • 언어 간 인터페이스를 자동화 한다면?!
  • 22. 언어간 인터페이스 자동생성 C++ 소 스코드 (.h) C# 소스 코드 C++ 인 터페이스 C# 코드 C# 인터 페이스 C++ 코 드 2 3 4 1 CppSharp CXXI …
  • 23. C#을 위한 C++ 인터페이스 자동생성 CppSharp CXXI + Clang 1. C++ 헤더파일들을 파싱(!)하여 인터페이스들 분석 2. (C++ 인터페이스를 Mono에 노출하는 C++ 코드)와 이를 호출할 수 있는 C# 코드 생성 3. C# 코드에서 인터페이스 코드를 호출 4. C# 코드 컴파일시 인터페이스 코드를 함께 컴파일
  • 24. C++ 파싱 - Clang  LLVM 컴파일러의 C/C++ 파서  상용 제품 수준  Visual C++ 구문들도 인식  불완전한 구문에 의해 파싱이 실패하지 않음  libclang을 이용하여 스크립트 언어에서도 사용 가능, Python 모듈 기본 제공 – AST 생성 − libclang은 clang의 극히 일부의 기능만을 노출하므 로 커스터마이제이션 필요
  • 25. C++ 인터페이스 생성 예제 (CppSharp) // C++ 소스코드 class Foo { int variable; int DoSomething ( int arg1, std::string arg2 ); }; // 자동 생성된 C#용 인터페이스 코드 class Foo { // C++의 메모리 레이아웃 선언 struct Internal { … } // 사용자를 위한 편리한 인터페이스 int variable { get { return _Instance.ToPointer()->variable; } set { _Instance.ToPointer()->variable = value; } } int DoSomething( int arg1, string arg2 ) { return Internal.DoSomething( _Instance, arg1, arg2 ); } }
  • 26. C++ 인터페이스 생성 예제 (Embedded) // C++ 소스코드 #define EXPORT __attribute__((annotate(“ExportToMono”))) class EXPORT Foo { int variable; int DoSomething ( int arg1, std::string arg2 ); }; + Clang // 자동 생성된 클래스 등록 코드 RegisterNativeClass<Foo>(); RegisterNativeClassVariable<Foo,int>( “variable”, offsetof(Foo, variable) ); RegisterNativeClassMethod<Foo,int,int,std::string>( “DoSomething”, &Foo::DoSomething );
  • 27. C++ 인터페이스 생성 예제 (Embedded) // 자동 생성된 클래스 등록 코드에 의한 실제 내부 작동 RegisterNativeClass<Foo>(); // Foo 타입에 대한 RTTI등 각종 기본 정보들 등록 RegisterNativeClassVariable<Foo,int>( “variable”, offsetof(Foo, variable) ); // C#에서 호출할 accessor 메소드 등록 int NativeGetInt( void* nativeObject, int offset ); mono_add_internal_call( “NativeGetInt”, &NativeGetInt ); void NativeSetInt( void* nativeObject, int offset, int value ); mono_add_internal_call( “NativeSetInt”, &NativeSetInt ); RegisterNativeClassMethod<Foo,int,int,std::string>( “DoSomething”, &Foo::DoSomething ); // C#에서 호출할 메소드 등록 static int Foo_DoSomething( Foo* nativeObject, int arg1, std::string arg2 ) { nativeObject->DoSomething( arg1, arg2 ); } mono_add_internal_call( “Foo.NativeCall_DoSomething”, &Foo_DoSomething );
  • 28. C++ 인터페이스 생성 예제 (Embedded) // 자동 생성된 C#용 인터페이스 코드 class Foo { // C++의 메소드들 등록 [MethodImplAttribute(MethodImplOptions.InternalCall)] extern int NativeCall_DoSomething( IntPtr nativeObject, int arg1, string arg2 ); // 사용자를 위한 편리한 인터페이스 int variable { get { return NativeGetInt( nativeObject, 4 ); } set { NativeSetInt( nativeObject, 4 ); } } int DoSomething( int arg1, string arg2 ) { return NativeCall_DoSomething( nativeObject, arg1, arg2 ); } }
  • 29. C++를 위한 C# 인터페이스 자동생성 1. .NET reflection을 사용하여 DLL 안의 인터페이스 들 추적 2. DLL 인터페이스를 호출할 수 있는 C++ 코드 생성 3. C++ 게임코드에서 인터페이스 코드를 통해 DLL의 코드를 C++ 처럼 호출 4. C++ 게임코드 컴파일시 인터페이스 코드를 함께 컴파일
  • 30. C# 인터페이스 생성 예제 (Delegate) // 자동 생성된 C# 인터페이스 코드 partial class Foo { void ExposeToNative() { RegisterMonoMethod( 0, () => { return variable; } ); // Get_variable RegisterMonoMethod( 1, (int value) => { variable = value; } ); // Set_variable RegisterMonoMethod( 2, DoSomething ); // DoSomething } } // 자동 생성된 C++ 인터페이스 코드 class Foo { int Get_variable() { monoMethods[0](); } void Set_variable( int value ) { return monoMethods[1]( value ); } int DoSomething( int arg1, std::string arg2 ) { return monoMethods[2]( arg1, arg2 ); } }; delegate를 native 함수 포인터로 전달 RegisterMonoMethod에 의해 등록된 함수 포인터
  • 31. C# 인터페이스 생성 예제 (Embedded) // C# 소스코드 [Export] class Foo { // 자동 생성된 C++용 인터페이스 코드 class Foo { int variable; int DoSomething( int arg1, string arg2 ) { … } } int Get_variable() { void* ret = mono_runtime_invoke( monoClass, monoObject, “get_variable” ); return *(int*)ret; } void Set_variable( int value ) { mono_runtime_invoke( monoClass, monoObject, “set_variable”, [&value] ); } int DoSomething( int arg1, std::string arg2 ) { void* ret = mono_runtime_invoke( monoClass, monoObject, “DoSomething”, [&arg1, mono_string_new_wrapper(arg2)] ); return *(int*)ret; } };
  • 33. 언어 간 결합의 깊이 모듈 간 결합 다른 객체 간 결합 객체 수준 결합 C++ Class C++ variables C++ methods C# Class C# variables C# methods Hybrid Class C++ variables C# variables C++ methods C# methods 오브젝트 참조 클래스 형 변환 C++ 기능 모듈 표준 호출 단순 타입 C# 기능 모듈 개체 생명주기 관리
  • 34. 객체 수준 결합 단일 메모리의 구역 분할 • C# 클래스 선언에서 C++ 클래스의 영역 미리 선언 필요 • 개체의 수명은 C#에 의해서만 관 리되어야 함 • C++ new/delete 사용 불가
  • 35. 객체 수준 결합 개체 분할, 논리적 결합 • 독립적인 C++개체와 C#개체 • 필요할 때에만 상대개체 생성 가 능 • 자동생성된 소스코드 빌드에 유리 (partial class) • 개체 수명관리가 핵심
  • 36. Garbage Collection vs new/delete C++ 개체가 소유자 mono_gchandle_new mono_gchandle_free C# 개체가 소유자 상호 참조 new / delete gchandle refcount
  • 37. 상대 개체 동적생성 예제 // 자동생성된 C++용 인터페이스 코드 class FooProxy { FooProxy( Foo* nativeObject ) { // C#측의 Foo 개체가 없으면 생성 } int DoInCS( int arg ) { // C#측의 Foo.DoInCS 호출 } }; // C# 소스코드 class Foo : public NativeBound { int DoInCS( int arg ) { … } } // C++ 소스코드 class Foo : public MonoBound { int DoInCPP( int arg ) { return FooProxy(this).DoInCS(arg); } }; 성능 주의
  • 38. 삭제 - Garbage Collector 연동 살아있는 쌍 GC 활성화 Native 삭제 GC handle 3 1 Mono GC에 의 해 제거 가능 Mono GC에 의 해 제거 방지 Mono GC Native GC 0 Mono GC에 의해 제거됨 삭제됨 참조 카운트 GC handle 삭제
  • 39. 최종 형태 Data Engine 부분 최적화 과거의 게임코드
  • 40. 결론 Roslyn .NET Native, IL2CPP CppSharp, Script# 거의 모든 플랫폼에서 .NET과 C# 사용 가능 언어간 혼합의 자동화 → 더욱 높은 생산성과 이식성 .NET과 C#은 여전히 진화중
  • 43. 참고자료 .NET – Reflection: http://msdn.microsoft.com/en-us/library/f7ykdhsy(v=vs.110).aspx – Garbage Collection: http://msdn.microsoft.com/en-us/library/0xy59wtx(v=vs.110).aspx Mono – http://www.mono-project.com – Compiling Mono: http://www.mono-project.com/docs/compiling-mono/compiling-from-git/ – Embedding Mono: http://www.mono-project.com/docs/advanced/embedding/ – InterOp with Native: http://www.mono-project.com/docs/advanced/pinvoke/ – CppSharp: https://github.com/mono/CppSharp – CXXI: http://tirania.org/blog/archive/2011/Dec-19.html – Mono for Unreal Engine: http://mono-ue.github.io/ Clang – http://clang.llvm.org – Python with Clang: http://eli.thegreenplace.net/2011/07/03/parsing-c-in-python-with-clang
  • 44. iOS 시뮬레이터용 Mono 런타임 configure • --build=i386-apple-darwin13.0.0 • CC, CXX=<Xcode configure path>/Contents/Developer/Platforms/iPhoneSimulator.p latform/Developer/usr/bin 안의 gcc와 g++ • CFLAGS, CXXFLAGS – -arch i386 –miphoneos-version-min=<최소지원버전> – -isysroot=<Xcode path>/Contents/Developer/Platforms/iPhoneSimulator.platform/Deve loper/SDKs/iPhoneSimulator<버전>.sdk • LD, AS, AR, LIBTOOL, STRIP, RANLIB=<iPhoneSimulator SDK>/usr/bin 안에 있는 툴들 사용
  • 45. iOS 기기용 Mono 런타임 configure • --host=arm-apple-darwin10 • --target=arm-apple-darwin10 • CC, CXX=<Xcode Mono 3.2의 경우 XCode 4.x를 configure 사용해야 함 path>/Contents/Developer/Toolchains/XcodeDefault.xctoolc hain/usr/bin 안의 clang과 clang++ • CFLAGS, CXXFLAGS – -arch armv7 – -isysroot=<Xcode path>/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SD Ks/iPhoneOS???.sdk • LD, AS, AR, LIBTOOL, STRIP, RANLIB=<Xcode path>/Contents/Developer/Platforms/iPhoneOS.platform/Dev eloper/usr/bin 안에 있는 툴들 사용
  • 46. Android 기기용 Mono 런타임 configure • --host=arm-linux-androideabi • --target=arm-linux-androideabi • CC, CXX=<Xcode path>/Contents/Developer/Toolchains/XcodeDefault.xctoolc hain/usr/bin 안의 clang과 clang++ • CFLAGS, CXXFLAGS – -march=armv7-a – -mfloat-abi=softfp – -mfpu=neon – --sysroot=<NDK_ROOT>/platforms/android-<version>/arch-arm • LD, AS, AR, LIBTOOL, STRIP, RANLIB 설정 불필요 • --libdir <NDK_ROOT>/platforms/android-<version>/arch-arm/ usr/lib configure
  • 47. C++ → Lua 예제 // 자동 생성된 클래스 등록 코드에 의한 실제 내부 작동 RegisterNativeClass<Foo>(); // 클래스를 lua table로 생성 lua_createtable( “Foo” ); RegisterNativeClassVariable<Foo,int>( “variable”, offsetof(Foo, variable) ); // lua table에 getter/setter 멤버 함수들 등록 lua_pushcclosure( “Get_variable”, &NativeGetInt ); lua_pushcclosure( “Set_variable”, &NativeSetInt ); RegisterNativeClassMethod<Foo,int,int,std::string>( “DoSomething”, &Foo::DoSomething ); // lua table에 멤버 함수 호출자 등록 lua_pushcclosure( “DoSomething”, &Foo_DoSomething ); // 자동 생성된 lua용 인터페이스 코드 - 주석 또는 Lua Checker 용도 외에는 필요 없음 Foo = { Get_variable = function(), Set_variable = function( int_value ), DoSomething = function( int_arg1, string_arg2 ) } 명시적 accessor 대신 __index, __newindex로 구현 가능
  • 48. Lua → C++ 예제 // lua 소스코드 Foo = { variable = 0, int_DoSomething = function( int_arg1, string_arg2 ) … end // 자동 생성된 C++용 인터페이스 코드 } class Foo { int Get_variable() { return lua_tointeger( “variable” ); } void Set_variable( int value ) { lua_pushinteger( “variable”, value ); } int DoSomething( int arg1, std::string arg2 ) { lua_pushinteger( arg1 ); lua_pushstring( arg2 ); lua_pcall( “DoSomething” ); return lua_tointeger( STACK_TOP ); } };