상세 컨텐츠

본문 제목

android 안드로이드 NDK에서 C++ STL 사용 과련

스마트기기개발관련/OpenGL (그래픽, 게임)

by AlrepondTech 2020. 9. 18. 05:52

본문

반응형

 

 

 

=================================

=================================

=================================

 

 

 

 

 

 

 

이클립스 CDT 에서 NDK 로 C++ STL을 쓸떄 에러가 난다.

 

해당 프로젝트에 오른쪽 마우스로 속성에 들어간다음.

 "C/C++ General->Paths and Symbols"  란에 들어간다.

거기에서 add 추가 버튼을 누루고

 

${ANDROID_NDK_ROOT}\sources\cxx-stl\stlport\stlport

 

을 설정해 주면 된다. 

 

추가:

ANDROID_NDK_ROOT <- 는 자신이 설정한 NDK 루트 환경변수.

환경변수가 없으면 NDK 설치 경로를 써도 된다

 

발췌: http://stackoverflow.com/questions/9458208/using-the-stl-with-android-ndk-c

I had the same problem, and then realized that I need to put: APP_STL := stlport_static

in Application.mk, not Android.mk ... doh

Then I needed to add: ${ANDROID_NDK_ROOT}\sources\cxx-stl\stlport\stlport

to the include paths in eclipse to make it not complain in the UI about errors

 

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://blog.naver.com/harksoo1974?Redirect=Log&logNo=70100620563

 

[NDK R5] 기준

 

subtle ABI(Application Binary Interface)

  • ARM의 CPU와 인터페이스 하기 위한 표준 규약인것 같음.

 

toolchain 이란?

  • 원하는 target system의 sw를 개발하기 위한 host system의 compile 환경을 말함.
  • Compile 환경은 주로 Target과 host가 다르기 때문에 cross-compile 환경 이라고 함.

 

Android는 JNI 를 통해서 native code를 사용할 수 있도록 지원함.

 

JNI(Java Native Interface)?

  • Java가 JVM에 native method를 적재(locate)하고 수행(invoke)할 수 있도록 한다.
  • JNI가 JVN 내에 포함 되므로써, JVM이 호스트 운영체제상의 입출력, 그래픽스, 네트워킹, 스레드와 같은 긴으들을 작동하기 위한 로컬시스템호출(local system calls)을 수행 할 수 있도로 한다.

 

Android NDK R5 부터 STL을 지원을 한다.

 

Application.mk 을 JNI 폴더에 생성

Application.mk에 APP_STL := stlport_shared( or stlport_static) 항목 추가

현재(Android NDK R5)는 STL의 전체 기능을 제공은 stlport에서만 제공 (APP_STL :=system : gnu stl 사용)

 

예)

APP_STL := stlport_static

 

참조 :

명령어 : install. rm, mv, awk, cp, mkdir

명령어: toolchains 컴파일러 사용

android-ndk-r5/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-ndroideabi-g++

android-ndk-r5/toolchains/arm-linux-androideabi-4.4.3/prebuilt/windows/bin/arm-linux-androideabi-ar

 

$ANDROID_NDK_ROOT/ndk-build -B V=1 실행을 하면

컴파일 시에 jni 위의 폴더에 사용하고자 하는 프로젝트의 "AndroidManifest.xml "를 넣어서 컴파일 하도록 한다.

위의 파일이 있을 경우 컴파일이 되면, gdb.setup, gdbserver 가 추가적으로 생성이 된다.
1. 컴파일을 한다.

(arm-linux-ndroideabi-g++ )

2. 아카이브 처리 

(arm-linux-androideabi-ar)

3. 라이브러리 복사

4. 링크를 실행

(arm-linux-ndroideabi-g++ )

5. install 실행한다.

 

실행 로그

===============================================================================================

 

harksoo@harksoo-PC ~/android-ndk-r5/App/ShowMeInterface/jni
$ /home/harksoo/android-ndk-r5/ndk-build
Gdbserver      : [arm-linux-androideabi-4.4.3] libs/armeabi/gdbserver
Gdbsetup       : libs/armeabi/gdb.setup
Compile++ thumb  : ShowMeInterface <= jniShowMeInterface.cpp
Compile++ thumb  : ShowMeInterface <= Common.cpp
Compile++ thumb  : ShowMeInterface <= HttpSocket.cpp
Compile++ thumb  : ShowMeInterface <= msgBody.cpp
Compile++ thumb  : ShowMeInterface <= Parameter.cpp
Compile++ thumb  : ShowMeInterface <= ShowMeInterface.cpp
Compile++ thumb  : ShowMeInterface <= stringUtil.cpp
Compile++ thumb  : ShowMeInterface <= trace.cpp
Compile++ thumb  : ShowMeInterface <= UpdateParam.cpp
SharedLibrary  : libShowMeInterface.so
Install        : libShowMeInterface.so => libs/armeabi/libShowMeInterface.so

 

===============================================================================================

 

cygwin에서 drive 설정 방법

cd /cygdrive/d

 

NDK의 라이브러리를 사용하는 방법

: windows의 LIB, Dll 의 배포와는 다르게 NDK는 함수 헤더파일을 만들어서 배포하지 않는다.

  JAVA 클래스에 interface할 함수 정의를 한 후 이것에 대하여 헤더파일을 생성한다.(javah 이용)

  이 헤더 파일과 동일한 함수 정의로 선언하여 처리하면 된다.

  1. Eclips로 Android Project를 생성해야 한다.
  2. Activity Class에 Native function을 설정해야 한다.
  3. 해당 프로젝트의 bin에 가서 "javah com.test.HelloJni.HelloJniActivity(경로에 클래스명 포함)" 를 실행. (프로젝트 생성시 Activity  class 이름임)
    NDK에서 사용하는 원시 함수의 헤더파일을 생성해준다.
    예)
    harksoo@harksoo-PC /cygdrive/d/workspace/HelloJni/bin$ javah com.mtelo.ShowMeInterface.ShowMeInterface
  4. 생성된 해더 파일의 함수와 구현코드의 함수명을 같게 해줘야 한다.
    예) jstring Java_com_test_HelloJni_HelloJniActivity_stringFromJNI( JNIEnv* env, jobject thiz )
  5. NDK lib를 만들 폴더 생성, 그안에 JNI 폴더 생성, Android.mk 생성, Application.mk  생성한다.
    Android.mk의 내용
    -> 일반적인 LIB 생성 내용과 동일 : TODO : 추후 내용 추가 예정

    Applicatioin.mk 의 내용
    (아래의 내용 기제시 STLPORT의 STL를 사용할 수 있다.)
    stlport_shared일 경우 동적링크이기 때문에 해당 파일을 같이 배포를 해야 합니다. : TODO : 테스트 안함.

    APP_STL := stlport_static or APP_STL := stlport_shared

  6. JNIEnv* env 를 접근시에 (외부로 데이터를 줄 경우) : 
    C는 (*env)->NewStringUTF(env, "Hello from JNI !") 형식을 사용하지만,
    C++는 env->NewStringUTF(s.c_str()); 형식을 사용하여 구현한다.
    예)
    jniEnv->NewStringUTF(fieldValue);

    확인안된 방법
    const char* reschr2 = jniEnv->GetStringUTFChars(fieldName, JNI_FALSE);
    jniEnv->ReleaseStringUTFChars(fieldName, reschr2);
    jniEnv->DeleteLocalRef(fieldName);
  7. 외부에서 데이터를 받을 경우

 

JAVA 타입과 C/C++ 타입의 맵핑 테이블

참조 : http://gcc.gnu.org/java/papers/native++.html

Java type C/C++ typename Description
byte jbyte 8-bit signed integer
short jshort 16-bit signed integer
int jint 32-bit signed integer
long jlong 64-bit signed integer
float jfloat 32-bit IEEE floating-point number
double jdouble 64-bit IEEE floating-point number
char jchar 16-bit Unicode character
boolean jboolean logical (Boolean) values
void void no value

 

 

 

 

=================================

=================================

=================================

 

 

 

출처: http://stackoverflow.com/questions/8686931/eclipse-cdt-fails-to-find-stl-symbols-in-ndk-project

 

Eclipse-CDT fails to find STL symbols in NDK project

I am trying to write a simple Android application using the NDK and C++. Specifically, I'd like to use the gnustdc++ included with the newest version of the NDK (r7). The JNI library has compiled and worked perfectly fine as C, but now that I'm trying to introduce C++, I've run into some issues.
I have added ${NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/include/ to my project's include paths, and the #includes inline are resolved. However, attempting to actually use any STL class (such as vector) results in Symbol 'vector' could not be resolved.
All of the standard C symbols imported from <stdlib.h> and such work as well, until I try to replace the #include with <cstdlib>. Then it fails with Function 'malloc' could not be resolvedand so forth.
Oddly enough, adding the stlport headers (in ${NDK_ROOT}/sources/cxx-stl/stlport/stlport) fixes all of my issues. However I am linking in GNU C++, not STLPort, so this is an inconvenient and improper "solution" at best. It seems odd that these headers would work but the others would not. Is Eclipse failing to index or resolve the GNU C++ headers?
Android.mk
Application.mk
I am trying to write a simple Android application using the NDK and C++. Specifically, I'd like to use the gnustdc++ included with the newest version of the NDK (r7). The JNI library has compiled and worked perfectly fine as C, but now that I'm trying to introduce C++, I've run into some issues.
I have added ${NDK_ROOT}/sources/cxx-stl/gnu-libstdc++/include/ to my project's include paths, and the #includes inline are resolved. However, attempting to actually use any STL class (such as vector) results in Symbol 'vector' could not be resolved.
All of the standard C symbols imported from <stdlib.h> and such work as well, until I try to replace the #include with <cstdlib>. Then it fails with Function 'malloc' could not be resolvedand so forth.
Oddly enough, adding the stlport headers (in ${NDK_ROOT}/sources/cxx-stl/stlport/stlport) fixes all of my issues. However I am linking in GNU C++, not STLPort, so this is an inconvenient and improper "solution" at best. It seems odd that these headers would work but the others would not. Is Eclipse failing to index or resolve the GNU C++ headers?
Android.mk
Application.mk
Edit: I set up my project based on:
http://mhandroid.wordpress.com/2011/01/23/using-eclipse-for-android-cc-development/
android c++ eclipse android-ndk eclipse-cdt
 

3 Answers

activeoldestvotes

Read this, it has the solution:
http://comments.gmane.org/gmane.comp.handhelds.android.ndk/14371
The summary, in case the link dies some day is this:
It's a bug in the gnustl_shared module declaration. Sorry about that, it will be fixed in the next release. In the meantime, you can manually change $NDK/sources/cxx-stl/gnu-libstdc++/Android.mk and replace the line that says:
LOCAL_EXPORT_LDLIBS := $(LOCAL_PATH)/libs/$(TARGET_ARCH_ABI)/libsupc++.a
with:
LOCAL_EXPORT_LDLIBS := $(call host-path,$(LOCAL_PATH)/libs/$(TARGET_ARCH_ABI)/libsupc++.a)
 
In CPLUSPLUS-SUPPORT.html it is stated that for "System runtime" std::vector is not supported. So you should try gnustl or stlport runtime. From this document:
[EDIT]
I have missed that you included APP_STL, in my example project I am able to use vector but only with APP_STL := gnustl_static, with APP_STL := gnustl_shared I am getting error:
arm-linux-androideabi-g++.exe: /cygdrive/c/Android/android-ndk/sources/ cxx-stl/gnu-libstdc++/libs/armeabi/libsupc++.a: No such file or directory
explained here:
http://groups.google.com/group/android-ndk/browse_thread/thread/050965b03c908fe5
I tried to reproduce your problem but with no luck
 
I know it's not a perfect solution, but at least it'll let you click "run" or "debug" through Eclipse:
  • Right click on your Android C++ project and select Properties.
  • Under C/C++ General, click "Code Analysis"
  • Switch to "Use project settings"
  • Switch any errors you're receiving due to using the vector class to be "warnings".
For me, the errors I've needed to switch so far are:
  • "Symbol is not resolved"
  • "Member declaration not found"
  • "Invalid template argument"
  • "Invalid arguments"
  • "Method cannot be resolved"
Like I said, it's not perfect and you might miss real errors due to this, but you still get the ability to usually select "Go To Declaration" and some syntax checking abilities, as well as the ability to launch your program. The ndk-build step will catch any real errors anyway, so it's really not a huge loss. Honestly, I'm not sure of the source of this issue. It's likely got to be an Eclipse bug.
Off topic but relevant: you can also use the ndk-gdb through eclipse. The tutorial is on the blog linked to the OP, but here's a direct link anyway.
Best of luck!
Edit (followup):
I've since figured out a way to get around this problem, at least on my box. The OP said that including the STLPORT headers worked for him. It didn't for me, at first. I had to destroy my Eclipse project and start fresh (for some reason, it wouldn't let me remove some include definitions). Adding STLPORT fixed some issues, but in ndk r7b, I was still getting weird errors (e.g. NULL was not defined even after including stddef). I ended up having to include the x86 headers too. These should largely overlap with the arm ones, however, it's useful to have the arm ones 'on top' in the include order.
So, if you've been running into the same issue as I was, add
$NDK_DIR/platforms/android-14/arch-x86/usr/include
to your list of eclipse includes as well.

[출처] [NDK R5] NDK에서 C++ STL 사용|작성자 이쁜우리

 

 

 

=================================

=================================

=================================

 

 

 

 

 

반응형


관련글 더보기

댓글 영역