C/C++는 자바,Android,Objective-C 3 대 플랫폼 에서 혼합 프로 그래 밍 을 실현 합 니 다.
16572 단어 Java、AndroidObjective-C프로 그래 밍
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 컴 파일 개발 을 권장 합 니 다.연상 기능 은 매우 우호 적 이 고 컴 파일 속도 가 빠 르 며 디 버 깅 도 매우 편리 합 니 다.
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 라 이브 러 리 참조
이상 포획
// 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.플랫폼 과 관련 된 방법 을 사용 하지 않 고 이식 에 문제 가 생기 지 않도록 한다
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 대 플랫폼 에서 응용 프로그램 을 개발 한 자료 정리 입 니 다.추 후 관련 글 을 계속 정리 하 겠 습 니 다.본 사이트 에 대한 지원 에 감 사 드 립 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
NSScrollView의 NSTextView에 Padding을 제공문자가 겹치는 것이 조금 비좁기 때문에 스크롤 막대에 여백을 사용하고 싶습니다 다음은 목표 NSTextView 의 커스텀 클래스를 작성한다. 이미지로서는… 주위에 여백을 취한다(상하·좌우가 각각 대상) 원점 이동 (...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.