Upload
sang-don-kim
View
2.690
Download
1
Embed Size (px)
Citation preview
김성엽 / ㈜팁스웨어
Speaker
• MVP (Visual C++)
• ㈜팁스웨어 대표
• tipssoft.com 개발 커뮤니티 운영자
• 한이음 IT 멘토
blog.naver.com/tipsware
tipsware
Agenda
NDK &
Cross-Platform
Visual Studio
Emulator
Android App
Development
Cross-Platform
DEMO
NDK & Cross-Platform 기술 소개
VS2015에 추가된 Android Emulator
소개 및 시연
Android App 과 Win32 App 개발
시연
Android App & Native App 개발
The NDK is a toolset that allows you to implement parts of your app using native-code languages such as C and C++
- developer.android.com -
What is the NDK? Native Development Kit
Android Playstore App Top50 (U.S.)
More Platforms = More Opportunities
• 더 큰 시장에서 더 많은 기회를 얻기 위해 Desktop App
개발자들도 모바일 앱 개발을 필요로 한다
• C/C++ 로 Android Framework 확장을 위한 것이 아닌
NDK 만을 사용한 Android App 개발이 가능하다
• 최소한의 자바 문법만 사용하여 NDK 로 개발 후 JNI 를
사용하여 연동하는 안드로이드 앱을 개발 할 수 있다
Cross-Platform
• 플랫폼(Platform) 이란 운영체제의 기반이 되는 기술의 집합체
• 두 가지 이상의 플랫폼에서 정상적으로 동작하는 것
• 기반이 다른 다수의 운영체제에서 공통으로 사용되는 것
Visual Studio 2015 Cross-Platform
하기 쉽다!
C++ IDE 로 Cross-Platform 개발이 가능하다!
code-editing 스타일을 사용할 수 있다!
• Cross-Platform 을 통해 코드를 하고 할 수 있다!
디버깅이 가능하다!
에뮬레이션이 가능하다!
Cross-Platform으로 무엇을 할 수 있는가?
Visual Studio Emulator for Android
Visual Studio Emulator 요구 사항
• Windows 8 Pro Edition 이상
• Virtual OS 및 Azure 에서는 실행 불가
• DHCP 설정, 자동 DNS 및 gateway 설정
• BIOS 가 반드시 아래 기능을 제공
• Hardware-assisted virtualization
• SLAT (Second Level Address Translation)
• DEP (Hardware-based Data Execution Prevention)
• Hyper-V 기능 활성화
• Hyper-V 에 대한 관리자 그룹 권한
Visual Studio Emulator Spec
Zoom, Rotation, Network, Location, Accelerometer, Battery, OpenGL, SD Card, Ca
mera, Audio playback, Keyboard Input, Screenshots, Version and Screen Size Confi
gurations, Drag&Drop APKs
Android SDK Manager
Emulator Demo
Native App 개발하기 - Step 1
• Native-Activity App 프로젝트 생성
1. 새 프로젝트에서 선택
생성
Native App 개발하기 - Step 2
• Native-Activity App 빌드하기
1. 사용 가능한 Emulator 목록에서 테스트할 하나를 선택
2. Hyper-V 기반 Emulator 는 만 지원
Native App 개발하기 - Step 3
• Native-Activity App 을 ARM Emulator 로 실행하기
1. AVD Manager 를 실행하여 Android용 Emulator 실행
2. USB 케이블을 사용하여 스마트폰에 Android App 배포
Native App 실행 흐름
ANativeActivity_onCreate
android_app_create
android_app_entry
android_main
android_app_destroy
Alooper_pollAll
process
이벤트가 존재하는가?
engine_draw_frame()
Native App 실행 흐름
process
이벤트의 종류는 무엇인가?
process_input
engine_handle_input
engine_draw_frame()
android_app_pre_exec_cmd
engine_handle_cmd
process_cmd
android_app_read_cmd
android_app_post_exec_cmd
OpenGL ES
(Open Graphic for Embedded Systems)
• Khronos Group 에서 임베디드 기기를 위해 C언어로 작성된 무료 그래픽 라이브러리
에서 주로 사용되는 3D 그래픽 라이브러리
• ES 버전은 OpenGL 에서 잘 사용되지 않는 API를 제거하고
• NDK 에서는 API Level 4부터 OpenGL ES 1.x 버전을 제공
• 현재 NDK API Level 18 부터는 사용 가능
(Embedded-System Graphics Library)
• 실제 하드웨어에 출력할 때는 해당 된 EGL API 사용
OpenGL ES
• 화면 좌표계
• 폭과 높이가 인 사각형
• 수학에서 사용하는 좌표계와 동일
• Task Bar 를 포함한 영역
• 색상 정보
• 0.0 ~ 1.0 사이 실수 값
• α(alpha) : 색상의 투명도
OpenGL ES
static void engine_draw_frame(struct engine* engine) { if (engine->display == NULL) return; glClearColor(1, 1, 0, 1); glClear(GL_COLOR_BUFFER_BIT); // 지우는 속성을 명시 // 좌표를 배열할 때는 시계 반대방향으로 배열 GLfloat pos[8] = { -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5 }; glEnableClientState(GL_VERTEX_ARRAY); glColor4f(1, 0, 0, 1); glVertexPointer(2, GL_FLOAT, 0, pos); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); glDisableClientState(GL_VERTEX_ARRAY); // 물리적 장치에 출력. 함수를 호출하지 않으면 에뮬레이터가 오동작 eglSwapBuffers(engine->display, engine->surface); }
OpenGL ES
• OpenGL ES 로 도형 그리기
• 출력 결과
GLfloat pos[8] = { -0.5, -0.5, 0.5, -0.5, 0.5, 0.5, -0.5, 0.5 };
Native App 사용자 입력 처리
process_input
android_main 함수의 Event Looper 에서 Event 체크
process
engine_handle_input
Native App 사용자 입력 처리 – Step 1
static int32_t engine_handle_input(android_app* app, AInputEvent *event) { engine *p_engine = (engine *)app->userData; if( == AINPUT_EVENT_TYPE_MOTION){ // 사용자가 터치나 드래그와 같은 모션 형식의 정보를 입력함
} else { // 사용자가 키를 입력함(AINPUT_EVENT_TYPE_KEY)
} return 1; }
• 사용자 입력의 Event Type 을 체크
: Key (Cancel 버튼, Power 버튼 등) 가 클릭됨
: 모션과 관련된 이벤트 발생
Native App 사용자 입력 처리 – Step 2
static int32_t engine_handle_input(android_app* app, AInputEvent *event) { engine *p_engine = (engine *)app->userData; if(AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION){ int32_t action_type = (event); if(action_type == AKEY_EVENT_ACTION_DOWN) // 화면 클릭 (터치 시작) else if(action_type == AKEY_EVENT_ACTION_UP) // 화면 클릭 해제 (터치 끝) else // 드래그 또는 멀티 터치 } return 1; }
• 사용자 입력 Event 의 행위를 체크
Native App 사용자 입력 처리 – Step 3
• 사용자 입력 Event 가 발생한 화면상의 좌표 값
• 위 함수를 통해서 얻은 좌표 값은 해상도를 기준으로 하는 좌표 값
• 현재 사용하는 장치의 해상도는 구조체에 width, height 에 저장됨
// 0 ~ (width – 1) 사이의 값 발생 int32_t x = AMotionEvent_getX(event, 0); // 0 ~ (height – 1) 사이의 값 발생 int32_t y = AMotionEvent_getY(event, 0);
Native App File I/O – Step 1
• 파일 입출력 권한 얻기
<uses-permission android:name=“android.permission. ” ></uses-permission> <uses-permission android:name=“android.permission. ” ></uses-permission>
AndroidManifest.xml
• 위 권한을 부여한 후, 생성한 앱을 배포하여
Device 에서 설치할 때 나오는 화면
Native App File I/O – Step 2
• 파일 입출력 권한 얻기 – C++ fstream 클래스
#include <fstream> using namespace std; ofstream tips_write_file(“/sdcard/tipssoft.dat”); if(tips_write_file.is_open()){ int jin = 0x0412; tips_write_file << jin; // jin 변수에 있는 정수 값을 파일에 쓴다 tips_write_file.close(); } ifstream tips_read_file(“/sdcard/tipssoft.dat”); if(tips_read_file.is_open()){ int jin = 0; tips_read_file >> jin; // 저장된 정수 값을 읽어서 jin 변수에 저장 tips_read_file.close(); }
Native App File I/O – Step 3
• 파일 입출력 권한 얻기 – C 표준 입출력 라이브러리
#include <stdio.h> FILE *p_write_file = fopen("/sdcard/tipssoft.dat", "wb"); if (p_write_file != NULL) { int jin = 0x0412; fwrite(&jin, 1, sizeof(int), p_write_file); fclose(p_write_file); } FILE *p_read_file = fopen("/sdcard/tipssoft.dat", "rb"); if (p_read_file != NULL) { int jin = 0; fread(&jin, 1, sizeof(int), p_read_file); fclose(p_read_file); }
Native App Socket – Step 1
• 인터넷 사용 권한 얻기
• 소켓 사용에 필요한 헤더 파일 추가
<uses-permission android:name=“android.permission. ”></uses-permission>
AndroidManifest.xml
• 위 권한을 부여한 후, 생성한 앱을 배포하여
Device 에서 설치할 때 나오는 화면
#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h>
Native App Socket – Step 2
int gh_socket = socket(AF_INET, SOCK_STREAM, 0); sockaddr_in srv_addr; srv_addr.sin_family = AF_INET; srv_addr.sin_addr.s_addr = inet_addr(“192.168.0.118”); srv_addr.sin_port = htons(25790); if (connect(gh_socket, (sockaddr *)&srv_addr, sizeof(srv_addr)) == 0) { char *p_string = “Hello~ tipssoft!!”; // (메시지 ID : 1) 문자열 한 개 전송 SendFrameData(gh_socket, 1, p_string, strlen(p_string) + 1); int data = 0x00000412; // (메시지 ID : 2) 정수 값 한 개 전송 SendFrameData(gh_socket, 2, (char *)&data, sizeof(data)); }
• 소켓을 생성하고 서버에 접속하는 코드
Native-Activity App Demo
Android App 개발하기 - Step 1
• Android 기본 App 프로젝트 생성
1. 새 프로젝트에서 선택
Android App 개발하기 - Step 2
• 솔루션에 라이브러리 추가
1. 새 프로젝트에서 선택
Android App 개발하기 - Step 3
• 생성한 라이브러리 참조
1. Android App 이 하도록 설정
Android App 개발하기 - Step 4
• 라이브러리의 C 소스 코드 작성
1. 함수 생성시 함수명은 아래와 같은 형식으로 작성
#include <jni.h>
#include <string.h>
extern “c” { jstring Java_com_MyJNI_MyJNI_getString(JNIEnv *env, jobject thisz) { return env->NewStringUTF(“Hello JNI”); } }
Android App 개발하기 - Step 5
• 안드로이드 앱의 JAVA 소스 코드 작성
public class MyJNI extends Activity { public native String getString(); static { System.loadLibrary(“MyLibrary”); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); tv.setText(getString()); setContentView(tv); } }
Android App Demo
Cross-Platform 개발 환경 구축
• Cross-Platform 은 동일한 소스를 기반으로 둘 이
상의 Platform 에서 동작하는 App 을 개발하는 것
를 이용하면 Cross-Platform 솔루
션을 만들 수 있다
• Visual C++ 에서는 Win32 Application, Android
App, iOS App 등을 동시에 개발할 수 있다
Cross-Platform Demo
Q & A
TIPS C/C++/MFC 무료 강좌 tipssoft.com
감사합니다.
http://aka.ms/td2015_again
TechDays Korea 2015에서 놓치신 세션은 Microsoft 기술 동영상 커뮤니티 Channel 9에서
추후에 다시 보실 수 있습니다.