SlideShare a Scribd company logo
1 of 48
두 마리 토끼를 잡기 위한 
C++ - C# 혼합 멀티플랫폼 
게임 아키텍처 설계 
㈜이노스파크 
Technical Director 
김성균
목차 
1. 개요 
2. C# (.NET) 실행환경 
3. 언어 간 인터페이스 결합 자동화 
4. 언어 간 개체 결합 
5. 결론 
6. 부록
동기 
 빠른 성능 
 구현의 자유성 
 높은 이식성 
− 코딩의 실수는 치명적 
− 낮은 생산성 
 높은 생산성 (문법, OOP …) 
 적절한 성능 
 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 ); 
} 
};

More Related Content

What's hot

[0410 박민근] 기술 면접시 자주 나오는 문제들
[0410 박민근] 기술 면접시 자주 나오는 문제들[0410 박민근] 기술 면접시 자주 나오는 문제들
[0410 박민근] 기술 면접시 자주 나오는 문제들MinGeun Park
 
[0821 박민근] 렌즈 플레어(lens flare)
[0821 박민근] 렌즈 플레어(lens flare)[0821 박민근] 렌즈 플레어(lens flare)
[0821 박민근] 렌즈 플레어(lens flare)MinGeun Park
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012devCAT Studio, NEXON
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략YEONG-CHEON YOU
 
Ndc14 분산 서버 구축의 ABC
Ndc14 분산 서버 구축의 ABCNdc14 분산 서버 구축의 ABC
Ndc14 분산 서버 구축의 ABCHo Gyu Lee
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현YEONG-CHEON YOU
 
Multiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theoremMultiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theoremSeungmo Koo
 
NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술
NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술
NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술Ki Hyunwoo
 
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)Heungsub Lee
 
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요NAVER D2
 
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019devCAT Studio, NEXON
 
Multithread & shared_ptr
Multithread & shared_ptrMultithread & shared_ptr
Multithread & shared_ptr내훈 정
 
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기강 민우
 
NDC2011 - 절차적 지형과 트렌드의 추적자들
NDC2011 - 절차적 지형과 트렌드의 추적자들NDC2011 - 절차적 지형과 트렌드의 추적자들
NDC2011 - 절차적 지형과 트렌드의 추적자들Jubok Kim
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012devCAT Studio, NEXON
 
강성훈, 실버바인 대기열 서버 설계 리뷰, NDC2019
강성훈, 실버바인 대기열 서버 설계 리뷰, NDC2019강성훈, 실버바인 대기열 서버 설계 리뷰, NDC2019
강성훈, 실버바인 대기열 서버 설계 리뷰, NDC2019devCAT Studio, NEXON
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현noerror
 
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션NHN FORWARD
 
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceKGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceXionglong Jin
 
이승재, 사례로 배우는 디스어셈블리 디버깅, NDC2014
이승재, 사례로 배우는 디스어셈블리 디버깅, NDC2014이승재, 사례로 배우는 디스어셈블리 디버깅, NDC2014
이승재, 사례로 배우는 디스어셈블리 디버깅, NDC2014devCAT Studio, NEXON
 

What's hot (20)

[0410 박민근] 기술 면접시 자주 나오는 문제들
[0410 박민근] 기술 면접시 자주 나오는 문제들[0410 박민근] 기술 면접시 자주 나오는 문제들
[0410 박민근] 기술 면접시 자주 나오는 문제들
 
[0821 박민근] 렌즈 플레어(lens flare)
[0821 박민근] 렌즈 플레어(lens flare)[0821 박민근] 렌즈 플레어(lens flare)
[0821 박민근] 렌즈 플레어(lens flare)
 
임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012임태현, MMO 서버 개발 포스트 모템, NDC2012
임태현, MMO 서버 개발 포스트 모템, NDC2012
 
실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략실시간 게임 서버 최적화 전략
실시간 게임 서버 최적화 전략
 
Ndc14 분산 서버 구축의 ABC
Ndc14 분산 서버 구축의 ABCNdc14 분산 서버 구축의 ABC
Ndc14 분산 서버 구축의 ABC
 
MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현MMOG Server-Side 충돌 및 이동처리 설계와 구현
MMOG Server-Side 충돌 및 이동처리 설계와 구현
 
Multiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theoremMultiplayer Game Sync Techniques through CAP theorem
Multiplayer Game Sync Techniques through CAP theorem
 
NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술
NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술
NDC2016 프로젝트 A1의 AAA급 캐릭터 렌더링 기술
 
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
[야생의 땅: 듀랑고] 서버 아키텍처 Vol. 2 (자막)
 
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
[2B7]시즌2 멀티쓰레드프로그래밍이 왜 이리 힘드나요
 
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019
유인호, <드래곤하운드>비주얼이펙트 연출, NDC2019
 
Multithread & shared_ptr
Multithread & shared_ptrMultithread & shared_ptr
Multithread & shared_ptr
 
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
[IGC 2017] 펄어비스 민경인 - Mmorpg를 위한 voxel 기반 네비게이션 라이브러리 개발기
 
NDC2011 - 절차적 지형과 트렌드의 추적자들
NDC2011 - 절차적 지형과 트렌드의 추적자들NDC2011 - 절차적 지형과 트렌드의 추적자들
NDC2011 - 절차적 지형과 트렌드의 추적자들
 
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
전형규, 가성비 좋은 렌더링 테크닉 10선, NDC2012
 
강성훈, 실버바인 대기열 서버 설계 리뷰, NDC2019
강성훈, 실버바인 대기열 서버 설계 리뷰, NDC2019강성훈, 실버바인 대기열 서버 설계 리뷰, NDC2019
강성훈, 실버바인 대기열 서버 설계 리뷰, NDC2019
 
NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현NDC12_Lockless게임서버설계와구현
NDC12_Lockless게임서버설계와구현
 
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
[2019] 언리얼 엔진을 통해 살펴보는 리플렉션과 가비지 컬렉션
 
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games ConferenceKGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
KGC 2016: HTTPS 로 모바일 게임 서버 구축한다는 것 - Korea Games Conference
 
이승재, 사례로 배우는 디스어셈블리 디버깅, NDC2014
이승재, 사례로 배우는 디스어셈블리 디버깅, NDC2014이승재, 사례로 배우는 디스어셈블리 디버깅, NDC2014
이승재, 사례로 배우는 디스어셈블리 디버깅, NDC2014
 

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

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

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

NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
NDC 2017 하재승 NEXON ZERO (넥슨 제로) 점검없이 실시간으로 코드 수정 및 게임 정보 수집하기
 
Google Protocol buffer
Google Protocol bufferGoogle Protocol buffer
Google Protocol buffer
 
20201121 코드 삼분지계
20201121 코드 삼분지계20201121 코드 삼분지계
20201121 코드 삼분지계
 
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
[TechDays Korea 2015] 녹슨 C++ 코드에 모던 C++로 기름칠하기
 
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
[Td 2015]녹슨 c++ 코드에 모던 c++로 기름칠하기(옥찬호)
 
Boost 라이브리와 C++11
Boost 라이브리와 C++11Boost 라이브리와 C++11
Boost 라이브리와 C++11
 
kics2013-winter-biomp-slide-20130127-1340
kics2013-winter-biomp-slide-20130127-1340kics2013-winter-biomp-slide-20130127-1340
kics2013-winter-biomp-slide-20130127-1340
 
Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나Hoons 닷넷 정기세미나
Hoons 닷넷 정기세미나
 
[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
[shaderx6]8.2 3d engine tools with c++cli
 
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
[Td 2015]windows, linux, mac 신경 안 쓴다. .net 2015와 더더 좋아지는 c# 살짝 훔쳐보기(김명신)
 
코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011코드 생성을 사용해 개발 속도 높이기 NDC2011
코드 생성을 사용해 개발 속도 높이기 NDC2011
 
Tech Update - The Future of .NET Framework (김명신 부장)
Tech Update - The Future of .NET Framework (김명신 부장)Tech Update - The Future of .NET Framework (김명신 부장)
Tech Update - The Future of .NET Framework (김명신 부장)
 
C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발C#을 사용한 빠른 툴 개발
C#을 사용한 빠른 툴 개발
 
The Future of .NET and C#
The Future of .NET and C#The Future of .NET and C#
The Future of .NET and C#
 
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
C# / .NET Framework로 미래 밥그릇을 챙겨보자 (Basic)
 
Domain Specific Languages With Groovy
Domain Specific Languages With GroovyDomain Specific Languages With Groovy
Domain Specific Languages With Groovy
 
Effective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshinEffective c++ chapter1 2_dcshin
Effective c++ chapter1 2_dcshin
 
Tech-days 미니 토요세미나 - 3회 C#편 PPT 자료
Tech-days 미니 토요세미나 - 3회 C#편 PPT 자료Tech-days 미니 토요세미나 - 3회 C#편 PPT 자료
Tech-days 미니 토요세미나 - 3회 C#편 PPT 자료
 
Ch09
Ch09Ch09
Ch09
 
프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~
프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~
프로그래밍 언어의 F1머신 C++을 타고 Windows 10 UWP 앱 개발의 세계로~
 

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

  • 1. 두 마리 토끼를 잡기 위한 C++ - C# 혼합 멀티플랫폼 게임 아키텍처 설계 ㈜이노스파크 Technical Director 김성균
  • 2. 목차 1. 개요 2. C# (.NET) 실행환경 3. 언어 간 인터페이스 결합 자동화 4. 언어 간 개체 결합 5. 결론 6. 부록
  • 3.
  • 4.
  • 5. 동기  빠른 성능  구현의 자유성  높은 이식성 − 코딩의 실수는 치명적 − 낮은 생산성  높은 생산성 (문법, OOP …)  적절한 성능  C++와 유사한 문법 − 저수준 제어 어려움 − 다른 환경과 연동 어려움
  • 6.
  • 7. 목표 언어간 코드 연동을 위한 작업량 최소화 코드를 다른 언어로 손쉽게 변환 • 성능이 중요한 기능 • 저수준 제어 • 외부 라이브러리 연동 • 빠른 구현과 잦은 변경이 필 요한 상위 수준의 기능들 • 성능이 중요하지 않은 코드
  • 8.
  • 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 ); } };