본문 바로가기
모바일/안드로이드프로그래밍

[C/C++] 안드로이드에서 C/C++로 개발해보기 - C++에서 받아온 문자열 출력하기

by 푸_푸 2022. 8. 14.
728x90

안드로이드에서 네이티브 프로그램으로 프로그래밍해보자.


1. Native C++로 먼저 프로젝트를 만들어준다. 

 

프로젝트명 : Chapter02


2. activity_main.xml

 

기본적으로 제공되는 xml파일을 사용한다. 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <TextView
      android:id="@+id/sample_text"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Hello World!"
      app:layout_constraintBottom_toBottomOf="parent"
      app:layout_constraintStart_toStartOf="parent"
      app:layout_constraintEnd_toEndOf="parent"
      app:layout_constraintTop_toTopOf="parent" />

  </androidx.constraintlayout.widget.ConstraintLayout>

 


3. MainActivity.java

 

1) 텍스트 뷰 연결

2) 문자열, 정수를 네이티브 함수로 넘김

3) 네이티브 함수의 결과를 화면에 출력시킴

4) getLine() 네이티브 함수

package com.example.chapter02;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView tv = findViewById(R.id.sample_text);

        //문자열과 정수를 네이티브 함수에 넘긴다
        String input = getLine("입력 값 : ", 100);
        //네이티브 함수에서 결과 값을 받아 화면에 출력시킨다.
        tv.setText(input);
    }

    //다음문장으로 getLine() 메소드가 네이티브 함수라는 사실을 알려준다.
    private native String getLine(String prompt, int value);

    static {
        System.loadLibrary("chapter02");
    }
}

 

4. native-lib.cpp

 

#include <android/log.h>

extern "C" JNIEXPORT jstring JNICALL
Java_com_example_chapter02_MainActivity_getLine(
        JNIEnv *env,
        jobject /* this */,
        jstring prompt,
        jint value) {
    const char *str = env->GetStringUTFChars(prompt, NULL); //자바의 문자열을 UTF-8로 변경
    if(str == NULL)
        return NULL;

    //기본 int 타입인 value는 변형없이 그대로 활용이 가능하다.
    //네이티브 함수로 받은 문자열과 int 타입의 정수를 LogCat 화면에 출력시킨다.
    __android_log_print(ANDROID_LOG_INFO, "App Debug", "%s(default %d) : ", str, value);

    //char 타입의 변수에서 사용한 메모리는 함수의 제어를 반환하기 전에 해제시켜 주어야 한다.
    env->ReleaseStringUTFChars(prompt, str);

    //새롭게 문자열을 입력 받는다.
    const char *buf = "안녕하세요";
    return env->NewStringUTF(buf);  //자바에서 사용하는 UTF-16으로 바꾸어서 반환한다,
}

[자바와 C/C++은 문자열 체계가 다르다]

- 네이티브 프로그램을 사용하기 위해서는 다음의 세 가지 함수가 필요하다.

 

1) 자바(UTF-16) 문자열을  C/C++에서 사용하는 UTF-8 문자열로 바꾸어 사용해야 하며,

    문자열 끝에 NULL값을 추가시켜 주어야 한다.

  • 생성 함수
const jbyte * GetStringUTFChars(jstring string, jboolean *isCopy) : <jni.h>

자바의 문자열을 UTF-8로 변환하면서 문자열 끝에 NULL을 추가시켜준다.

 

 

2) 자바에서는 가비지 콜렉션으로 자동으로 메모리를 해제해주지만 C/C++에서는 직접 할당, 반환해주어야 한다.

  • 해제 함수
void ReleaseStringUTFChars(jstring string, const jbyte *utf) : <jni.h>

 

GetStringUTFChars() 함수로 부터 반환받은 버퍼를 해제시킬 때 사용한다.

 

 

3) UTF-8 문자열을 그대로 반환하면 자바 프로그램에서 에러가 발생한다.

jstring NewStringUTF(JNIEnv *env, const char *bytes);

자바에서 사용하는 UTF-16으로 바꾸어준다.


 

위의 프로그램을 실행하면 "안녕하세요"라는 글자가 화면에 출력되는 것을 확인할 수 있다. 

 

728x90

댓글