C/C++는 자바,Android,Objective-C 3 대 플랫폼 에서 혼합 프로 그래 밍 을 실현 합 니 다.

안 드 로 이 드 와 iOS 개발 은 모두 C++개발 을 지원 하 며 코드 다 중 플랫폼 에서 사용 할 수 있다.또한 C++컴 파일 하기 어 려 운 특성 도 안 드 로 이 드 개발 에 코드 의 비밀 을 가 져 다 줄 수 있 고 다른 native 특성 도 코드 의 운행 효율 을 높 일 수 있다.
1.왜 C/C++를 사용 합 니까?
4.567917.이식 하기에 편리 하고 C/C++로 쓴 라 이브 러 리 는 다른 플랫폼 에서 다시 사용 하기에 편리 하 다4.567917.코드 의 보 호 는 자바 층 코드 가 쉽게 역 컴 파일 되 기 때문에 C/C+라 이브 러 리 의 반 환 난이도 가 비교적 크다4.567917.프로그램의 집행 효율 을 향상 시 키 고 고성능 의 응용 논리 에 C/C+개발 을 사용 하여 응용 프로그램의 집행 효율 을 향상 시 킬 것 이다4.567917.기 존의 오픈 소스 라 이브 러 리 를 방문 하려 면 바 텀 API 를 방문 하거나 C/C+만 있 는 라 이브 러 리 를 참조 해 야 합 니 다.
개발 도구 소개
안 드 로 이 드 스튜디오 는 C++와 자바 코드 를 동시에 작성 할 수 있 지만 작성 하면 컴 파일 하여 실행 할 수 있 습 니 다.그러나 연상 과 오류 알림 에 그다지 우호 적 이지 않 습 니 다.개인 적 으로 C+의 전체 코드 는 Visual Studio 나 Xcode 컴 파일 개발 을 권장 합 니 다.연상 기능 은 매우 우호 적 이 고 컴 파일 속도 가 빠 르 며 디 버 깅 도 매우 편리 합 니 다.
  • Visual Studio(PC)
  • Xcode(Mac)
  • Android Studio(멀 티 플랫폼)eclipse(다 중 플랫폼)세 번 째 줄 코드
    1.Objective-C 프로젝트 에서 C++를 사용 하 는 방법;
    Objective-C 에서 C/C++를 사용 하 는 것 은 매우 간단 합 니 다.m 접미사 파일 을 m 로 바 꾸 기만 하면 C++를 사용 할 수 있 습 니 다.우 리 는 보통 m 의 파일 을 전체 프로젝트 에 쓰 지 않 고 인 터 페 이 스 를 설계 하여 두 언어 간 의 다 리 를 만 들 수 있 습 니 다.그들 간 의 상호작용 은 이 인터페이스 에 만 있 습 니 다.
    요점:String 형식 변환
    
    // Objective-C(NSString) -> C++(std::string)
    NSString * ocString = @"Hello World,OC";
    std::string cppString = [ocString UTF8String];
    std::cout<<cppString<<std::endl;
    // C++(std::string) -> Objective-C(NSString)
    std::string cppString2 = "Hello World,C++";
    NSString *ocString2= [NSString stringWithCString:cppString2.c_str() encoding:[NSString defaultCStringEncoding]];
    NSLog(@"%@",ocString2);
    include 관련 파일 기억 해.
    #include
    #include
    2.일반 JAVA 프로젝트 에서 JNI 프로 그래 밍 사용
    저 는 MAC 에서 근무 하기 때문에 MAC 에서 JNI 개발 을 하 는 방법 을 소개 합 니 다.Windows 플랫폼 에서 의 Virtual Studio 도 간단 합 니 다.
    첫 번 째 단계:Xcode 다음 에 일반적인 C++프로젝트 를 만 듭 니 다.


    STEP 2:자바 VM 관련 프레임 워 크
    경로:
    /System/Library/Frameworks/JavaVM.framework/Frameworks/JavaNativeFoundation.framework/

    세 번 째 단계:헤더 파일 을 만 들 고 자바 와 의 대화 cntaoweiji_nativemodule_NativeDemo.h
    
    #include <JavaVM/jni.h>
    #ifndef _Included_cn_taoweiji_nativemodule_NativeDemo
    #define _Included_cn_taoweiji_nativemodule_NativeDemo
    #ifdef __cplusplus
    extern "C" {
    #endif
     JNIEXPORT jint JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_add
     (JNIEnv *, jclass, jint, jint);
     JNIEXPORT void JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_say
     (JNIEnv *, jclass, jstring);
     JNIEXPORT jstring JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_getInfo
     (JNIEnv *, jclass);
    
     JNIEXPORT void JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_nativeToJava
     (JNIEnv *, jclass, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    네 번 째 단계:NativeDemo.cpp 구현
    
    #include "cn_taoweiji_nativemodule_NativeDemo.h"
    #include <string>
    JNIEXPORT jint JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_add(JNIEnv *, jclass, jint param1, jint param2)
    {
     jint result = param1 + param2;
     return result;
    }
    JNIEXPORT void JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_say(JNIEnv *env, jclass, jstring param)
    {
     // std::string -> jstring
     const char *param_char = env->GetStringUTFChars(param, NULL);
     std::string str = param_char;
    }
    JNIEXPORT jstring JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_getInfo(JNIEnv *env, jclass)
    {
     // jstring -> std::string
     std::string str = "Hi,I am C++.";
     jstring result = env->NewStringUTF(str.c_str());
     return result;
    }
    JNIEXPORT void JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_nativeToJava(JNIEnv * env, jclass, jobject obj)
    {
     //   Java  
     jclass cls = env->FindClass("cn/taoweiji/nativemodule/NativeDemo");
     //int subtract(int param1, int param2) -> (II)I
     jmethodID mid = env->GetMethodID(cls, "subtract", "(II)I");
     int result = (int) env->CallIntMethod(obj, mid, 10, 2);
    // std::cout<<result<<std::endl;
     //        
     //String getInfo();
     //-> ()Ljava/lang/String;
    
     //PackageInfo getPackageInfo(String packageName, int flags);
     //-> (Ljava/lang/String;I)Landroid/content/pm/PackageInfo;;
    
    }
    
    
    다섯 번 째 단계:JNI 파일 을 컴 파일 하여 생 성 합 니 다.*8984°+B(Product->Build)를 누 르 십시오.
    컴 파일 후 파일

    자신의 컴퓨터 환경 에 따라 컴 파일 된 파일 을 찾 습 니 다.제 경 로 는?
    /Users/Wiki/Library/Developer/Xcode/DerivedData/DEMO_MAC_JNI-clxymnzifegyfaajsaattzgxqfbr/Build/Products/Debug/DEMO_MAC_JNI
    STEP 6:JNI 인터페이스 작성
    
    package cn.taoweiji.nativemodule;
    /**
     *              C++     
     * cn_taoweiji_nativemodule_NativeDemo.h
     */
    public class NativeDemo {
     public static native int add(int param1, int param2);
     public static native void say(String name);
     public static native String getInfo();
     public static native void nativeToJava(NativeDemo nativeDemo);
     public int subtract(int param1, int param2) {
     System.out.println("NativeDemo:" + String.format("%s - %s = %s", param1, param2, param1 - param2));
     return param1 - param2;
     }
    }
    
    
    
    STEP 7:C++호출
    
    public class Main {
     static {
     System.load("/Users/Wiki/Library/Developer/Xcode/DerivedData/DEMO_MAC_JNI-clxymnzifegyfaajsaattzgxqfbr/Build/Products/Debug/DEMO_MAC_JNI");
     }
     public static void main(String[] args) {
     System.out.println("Hello World!");
     int result = NativeDemo.add(1, 2);
     System.out.println("1+2=" + String.valueOf(result));
     NativeDemo.say("Hello,I am Java.");
     System.out.println("getInfo:" + NativeDemo.getInfo());
     NativeDemo.nativeToJava(new NativeDemo());
     }
    }
    
    3.ANDROID 항목 에 NDK 사용
    Android 의 JNI 개발,C++파일 은 독립 된 module 에 작성 해 야 합 니 다.자바 인터페이스 코드 는 app(module)에 작성 할 수도 있 고 C++와 같은 module 에 넣 을 수도 있 습 니 다.gradle 을 통 해 연 결 됩 니 다.자세 한 코드 는 데모 탐색 을 직접 다운로드 하 십시오.
    
    gradle  (NativeModule)
    apply plugin: 'com.android.library'
    android {
     compileSdkVersion 23
     buildToolsVersion "24.0.0 rc2"
     defaultConfig {
     minSdkVersion 14
     targetSdkVersion 23
     versionCode 1
     versionName "1.0"
     }
     buildTypes {
     release {
      minifyEnabled false
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
      ndk {
      moduleName "joyrun"
      stl "stlport_static"
      ldLibs "log"//    __android_log_print
      abiFilters "armeabi", "armeabi-v7a", "x86", "x86_64", "arm64-v8a"
      //add -fexceptions to allow throw error
      //add -w to "format not a string literal and no format arguments [-Werror=format-security"
      cFlags "-w -fexceptions"
      }
     }
     }
    }
    dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
    }
    
    JNI 인터페이스 작성
    
    // NativeDemo.java
    package cn.taoweiji.nativemodule;
    public class NativeDemo {
     public static native int add(int param1, int param2);
    }
    
    C++인터페이스 코드 를 작성 합 니 다.JNI 파일 디 렉 터 리 는 기본적으로 module/src/main/jni 입 니 다.gradle 설정 을 통 해 변경 할 수 있 습 니 다.
    
    // cn_taoweiji_nativemodule_NativeDemo.h
    #include <jni.h>
    #ifndef _Included_cn_taoweiji_nativemodule_NativeDemo
    #define _Included_cn_taoweiji_nativemodule_NativeDemo
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class: cn_taoweiji_nativemodule_NativeDemo
     * Method: add
     * Signature: (II)I
     */
    JNIEXPORT jint JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_add(JNIEnv *, jclass, jint, jint);
    #ifdef __cplusplus
    }
    #endif
    #endif
    
    
    // NativeDemo.cpp
    #include "cn_taoweiji_nativemodule_NativeDemo.h"
    JNIEXPORT jint JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_add(JNIEnv *, jclass, jint param1, jint param2)
    {
     jint result = param1 + param2;
     return result;
    }
    
    호출
    
    //     
    static {
     System.loadLibrary("joyrun");
    }
    //  
    int result = NativeDemo.add(1,2);
    Log.i("1+2=",String.valueOf(result));
    
    NDK 개발 요점
    컴 파일 파일 파일 분석
    NativeModule 컴 파일 후 생 성 된 aar 파일 접 두 사 를.zip 압축 해제 로 바 꾸 면 jni 파일 이 있 습 니 다.열 면"armeabi","armeabi-v7a","x86","x86"을 볼 수 있 습 니 다.64","arm 64-v8a"등 폴 더 를 열 면 lib 접두사 의 so 형식 파일 을 볼 수 있 습 니 다.이것 이 바로 컴 파일 된 native 층 파일 입 니 다.우리 가 평소에 인용 하 는 제3자 라 이브 러 리(바 이 두 지도)도 이러한 파일 을 우리 의 libs 폴 더 에 추가 해 야 합 니 다.서로 다른 이름 은 서로 다른 플랫폼 과 관련 된 컴 파일 파일 파일 을 대표 합 니 다.시장 에 있 는 대부분의 휴대 전 화 는 arm 구조 CPU 입 니 다.x86 구조의 핸드폰 은 거의 사용 하 는 사람 이 없다(genymotion 시 뮬 레이 터 는 x86 플랫폼 에 속한다).그래서 우 리 는 보통 앱 을 발표 할 때 x86 플랫폼 을 고려 하지 않 고 armeabi 파일 만 추가 하면 된다.그러나 개발 과정 에서 x86 의 so 파일 을 추가 하여 우리 가 시 뮬 레이 터 에서 실행 할 수 있 도록 하 는 것 을 권장 한다.
    실행 라 이브 러 리
    Android 플랫폼 은 마이크로 C 라 이브 러 리 지원 라 이브 러 리 를 가지 고 있어 시스템 라 이브 러 리 가 됩 니 다.이 라 이브 러 리 는 C 표준 라 이브 러 리,이상 지원,RTTI 지원 을 지원 하지 않 습 니 다.NDK 는 시스템 실행 라 이브 러 리 기능 을 보충 하기 위 한 추가 적 인 C++실행 라 이브 러 리 를 제공 합 니 다.
    C++실행 라 이브 러 리
    C++이상 지원
    C++RTTI
    C++표준 라 이브 러 리
    시스템 라 이브 러 리
    No
    No
    No
    GAbi++
    No
    Yes
    No
    STLport
    No
    Yes
    Yes
    GNU STL
    Yes
    Yes
    Yes
    1.STLportSTLport 는 개 원 된 다 중 플랫폼 의 C 표준 라 이브 러 리 로 이 루어 진다.그것 은 C 표준 라 이브 러 리 파일 의 전체 집합 과 RTTI 에 대한 지원 을 제공 합 니 다.
    2.GNU STLGNU 표준 C 라 이브 러 리 는 libstdc-v3 라 고도 부 르 며 Android NDK 의 가장 전면적 인 표준 C 라 이브 러 리 입 니 다.ISO 표준 C 라 이브 러 리 를 실현 하 는 것 을 목표 로 개발 중인 오픈 소스 프로젝트 입 니 다.
    gradle 설정
    STL 라 이브 러 리 참조
  • “armeabi”, “armeabi-v7a”, “x86”, “x86_64","arm 64-v8a"등 플랫폼 설정
  • C++출력 logcat 설정컴 파일 이상 해결
    이상 포획
    
    //   so     
    moduleName "joyrun"
    //   STL   
    stl "stlport_static"//gnustl_static
    //    __android_log_print
    ldLibs "log"
    abiFilters "armeabi", "armeabi-v7a", "x86", "x86_64", "arm64-v8a" //       
    //add -fexceptions to allow throw error
    //add -w to "format not a string literal and no format arguments [-Werror=format-security"
    cFlags "-w -fexceptions"
    
    LOGCAT 출력
    
    #include <android/log.h>
    #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "tag_joyrun", __VA_ARGS__)
    #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "tag_joyrun", __VA_ARGS__)
    LOGE("Hello Logcat");
    형식 변환
    
    // std::string -> jstring
    std::string str = "Hello World";
    jstring result = env->NewStringUTF(str.c_str());
    // jstring -> std::string
    jstring param;
    const char *param_char = env->GetStringUTFChars(param, NULL);
    std::string str = param_char;
    // jboolean     JNI_TRUE、JNI_FALSE
    
    C++JAVA 코드 호출
    //Java
    
    public static native void nativeToJava(NativeDemo nativeDemo);
    public int subtract(int param1, int param2) {
    Log.e("NativeDemo", String.format("%s - %s = %s", param1, param2, param1 - param2));
    return param1 - param2;
    }
    
    //C++
    
    JNIEXPORT void JNICALL Java_cn_taoweiji_nativemodule_NativeDemo_nativeToJava(JNIEnv * env, jclass, jobject obj)
    {
     //   Java  
     jclass cls = env->FindClass("cn/taoweiji/nativemodule/NativeDemo");
     jmethodID mid = env->GetMethodID(cls, "subtract", "(II)I");
     int result = (int) env->CallIntMethod(obj, mid, 10, 2);
    
     //        
     //String getInfo();
     //-> ()Ljava/lang/String;
     //PackageInfo getPackageInfo(String packageName, int flags);
     //-> (Ljava/lang/String;I)Landroid/content/pm/PackageInfo;;
    }
    
    
    JAVA 에서 C++인터페이스 코드 스 크 립 트 생 성
    파일:autojavah.sh
    
    #!/bin/sh
    export ProjectPath=$(cd "../$(dirname "$1")"; pwd)
    export TargetClassName="co.runner.app.jni.NativeDemo"
    export SourceFile="${ProjectPath}/app/src/main/java"
    export TargetPath="${ProjectPath}/jni-joyrun/src/main/jni"
    cd "${SourceFile}"
    javah -d ${TargetPath} -classpath "${SourceFile}" "${TargetClassName}"
    echo -d ${TargetPath} -classpath "${SourceFile}" "${TargetClassName}"
    
    5.C++대상 및 표준 라 이브 러 리 입문
    C++클래스 정의
    
    // Demo.hpp
    #ifndef Demo_hpp
    #define Demo_hpp
    #include <stdio.h>
    #include <string>
    class Demo{
    public:
     std::string name;
     int age = 0;
     void say();
     static int add(int param1,int param2)
     {
     return param1 + param2;
     }
    };
    #endif /* Demo_hpp */
    
    유형 방법의 실현
    
    // Demo.cpp
    #include "Demo.hpp"
    #include <iostream>
    void Demo::say()
    {
     std::cout<<"name = "<<name<<",age = "<<age<<std::endl;
    }
    
    대상 생 성 및 방문 대상 의 구성원
    
    //    
    Demo d1;
    Demo * d2 = new Demo;
    //      
    d1.say();
    //     
    d2->say();
    //      
    int result = Demo::add(1,2);
    std::cout<<"1 + 2 = "<<result<<std::endl;
    
    LIST 링크
    
    //include    
    #include <stdio.h>
    #include <iostream>
    #include <list>
    #include "Demo.hpp"
    //     
    std::list<Demo> * demos = new std::list<Demo>;
    Demo * demo = new Demo;
    demo->name = "Wiki";
    demo->age = 24;
    //        
    demos->push_back(*demo);
    demo = new Demo;
    demo->name = "Wiki2";
    demo->age = 25;
    //        
    demos->push_front(*demo);
    //       
    for (std::list<Demo>::iterator iter = demos->begin(); iter != demos->end(); ++iter) {
     iter->say();
    }
    //        
    for (std::list<Demo>::reverse_iterator iter = demos->rbegin(); iter != demos->rend(); ++iter) {
     iter->say();
    }
    //         
    std::list<Demo>::iterator iter = demos->begin();
    advance(iter, 1);
    iter->say();
    
    포인터,인용,값
    C++에서 함 수 는 여러 가지 다른 방법 으로 파 라 메 터 를 전달 할 수 있 습 니 다.예 를 들 어 지침,인용 또는 직접 값 을 전달 할 수 있 습 니 다.
    
    //     
    void handle1(Demo *p);
    //     
    void handle1(Demo& p);
    //    
    void handle1(Demo *demo);
    
    더미 와 창고 의 이해
    스 택(stack):운영 체제 에서 자동 으로 분배 되 고 함수 의 매개 변수 값,부분 변수의 값 등 을 저장 합 니 다.그 조작 방식 은 데이터 구조 중의 창고 와 유사 하 다.
    더미(hep):일반적으로 프로그래머 가 분배 하여 방출 합 니 다.만약 에 프로그래머 가 방출 하지 않 으 면 프로그램 이 끝 날 때 OS 에서 회수 할 수 있 고 분배 방식 은 체인 테이블 과 유사 합 니 다.
    
    Demo d1;// 
    Demo * d2 = new Demo;// 
    char c; //    
    char *p = new char[3]; //    ,      p;
    쓰레기 수 거
    new 와 C+delete 연산 자 는 메모리 의 연산 자 를 동적 으로 분배 하고 취소 하 는 데 사 용 됩 니 다.new 에서 나 온 대상 은 delete 를 통 해 메모 리 를 풀 어야 합 니 다.
    delete demos;
    6.개발 에 자주 사용 되 는 방법 및 주의사항(구덩이)
    시간 스탬프 획득 방법 long time=time(0);4.567917.so 파일 도 난 방지 문제 에 주의 하 세 요4.567917.플랫폼 과 관련 된 방법 을 사용 하지 않 고 이식 에 문제 가 생기 지 않도록 한다
  • JNI 인터페이스의 가방 이름 에는 밑줄''이 있어 서 는 안 됩 니 다.
  • 관련 소스 코드:
    Android: https://github.com/taoweiji/DEMO_NDK
    Objective-C: https://github.com/taoweiji/DEMO_CPP_OC
    MAC-JNI: https://github.com/taoweiji/DEMO_MAC_JNI
     이상 은 C/C++가 안 드 로 이 드 와 자바,Objective-C 3 대 플랫폼 에서 응용 프로그램 을 개발 한 자료 정리 입 니 다.추 후 관련 글 을 계속 정리 하 겠 습 니 다.본 사이트 에 대한 지원 에 감 사 드 립 니 다!

    좋은 웹페이지 즐겨찾기