김성엽 / 팁스웨어
Speaker MVP (Visual C++) 팁스웨어대표 tipssoft.com 개발커뮤니티운영자 한이음 IT 멘토 tipsware blog.naver.com/tipsware manager@tipsware.com
Agenda NDK & Cross-Platform Visual Studio Emulator Android App Development Cross-Platform DEMO NDK & Cross- Platform 기술소개 VS2015 에추가된 Android Emulator 소개및시연 Android App & Native App 개발 Android App 과 Win32 App 개발시연
What is the NDK? Native Development Kit 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 -
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 Alooper_pollAll android_app_create 이벤트가존재하는가? android_app_entry android_main process android_app_destroy engine_draw_frame()
Native App 실행흐름 process process_cmd 이벤트의종류는무엇인가? android_app_read_cmd android_app_pre_exec_cmd process_input engine_handle_cmd engine_handle_input android_app_post_exec_cmd engine_draw_frame()
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 사용자입력처리 android_main 함수의 Event Looper 에서 Event 체크 process process_input engine_handle_input
Native App 사용자입력처리 Step 1 사용자입력의 Event Type 을체크 : Key (Cancel 버튼, Power 버튼등 ) 가클릭됨 : 모션과관련된이벤트발생 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;
Native App 사용자입력처리 Step 2 사용자입력 Event 의행위를체크 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;
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 파일입출력권한얻기 AndroidManifest.xml <uses-permission android:name= android.permission. ></uses-permission> <uses-permission android:name= android.permission. ></uses-permission> 위권한을부여한후, 생성한앱을배포하여 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. AndroidManifest.xml ></uses-permission> 위권한을부여한후, 생성한앱을배포하여 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
감사합니다.
TechDays Korea 2015 에서놓치신세션은 Microsoft 기술동영상커뮤니티 Channel 9 에서추후에다시보실수있습니다. http://aka.ms/td2015_again