Both Android and iOS Development support C + + development and can be used in a set of code multi-platform. At the same time, C + + difficult to decompile the characteristics of the Android development can bring code confidentiality, and another native features can improve the efficiency of the operation of the code.
First, why use C + +
- Easy to transplant, the use of C + + Write library can be easily used on other platforms.
- Code protection, because Java layer code is very easy to be decompile, and C + + library reverse sinks more difficult.
- Increasing the execution efficiency of the program will require high performance application logic using C + + development to improve the execution efficiency of the application.
- Access to an existing open source library requires access to the underlying APIs or to some libraries that have only C + +.
Ii. Introduction of development tools
Although Android Studio can write both C + + and Java code at the same time, it can be compiled and run, but not very friendly to Lenovo and error hints, and personal advice that the overall code for C + + is compiled and developed using Visual Studio or Xcode, Lenovo is very friendly, Compilation speed is very fast, debugging is also very convenient.
- Visual Studio (PC)
- Xcode (MAC)
- Android Studio (multi-platform)
- Eclipse (multi-platform)
Third, the first line of code
1. How to use C + + in OBJECTIVE-C projects;
It is very simple to use C/objective-c in the just need to change the. m suffix file to. mm to use C + +, we usually do not write the. mm file to the entire project, but to design an interface to do the bridge between the two languages, the interaction between them is only in this interface.
Important: String type conversion
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);
Remember to include the relevant files
#include <stdio.h>
#include <iostream>
2. Using JNI programming in common Java projects
Since I am working under a Mac, here's how to do JNI development under a Mac, and virtual studio under the Windows platform is simple.
The first step: Create a common C + + project under Xcode
Step two: The framework of associative JAVAVM
Path:
/system/library/frameworks/javavm.framework/frameworks/javanativefoundation.framework/
Step three: Create a header file for interacting with Java cn_taoweiji_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
Fourth step: Create implementation 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)
{
/ / Call the Java method
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;
/ / Common type conversion examples
//String getInfo();
//-> ()Ljava/lang/String;
//PackageInfo getPackageInfo(String packageName, int flags);
//-> (Ljava/lang/String;I)Landroid/content/pm/PackageInfo;;
}
Step Fifth: Compile the Jni file and press ⌘+b (Product-> build).
Post-compile file
According to their own computer environment, look up the compiled files, my path is
/users/wiki/library/developer/xcode/deriveddata/demo_mac_jni-clxymnzifegyfaajsaattzgxqfbr/build/products/debug /demo_mac_jni
Sixth step: Write the Jni interface
Package cn.taoweiji.nativemodule;
/**
* Package name and class name must correspond to the preceding C + + header file
* 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
}
}
Seventh Step: Call 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. Using NDK in Android projects
Android's JNI development, C + + files must be written in a standalone module, Java interface code can be written in the app (module), and C + + can be placed in the same module, through the Gradle Association. Detailed code please download demo browsing
Gradle configuration (nativemodule)
Apply plugin: ' Com.android.library '
android {
compilesdkversion
Buildtoolsversion "24.0.0 RC2"
defaultconfig {minsdkversion targetsdkversion-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"//To resolve __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=forma T-security '
cflags '-w-fexceptions '}}}
dependencies {
Compile filetree ( Dir: ' Libs ', include: [' *.jar ']
}
Writing JNI Interfaces
Nativedemo.java
package cn.taoweiji.nativemodule;
public class Nativedemo {public
static native int add (int param1, int param2);
}
Write C + + interface code, JNI file directory default is Module/src/main/jni, can be changed through Gradle configuration
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;
}
Call
Statically loaded static
{
system.loadlibrary ("Joyrun");
}
Call
int result = Nativedemo.add (1,2);
LOG.I ("1+2=", string.valueof (result));
Iv. key points of NDK development
Compile file analysis
Change the Nativemodule-generated AAR file suffix to. zip decompression, you can find that there is a JNI file, open to see "Armeabi", "armeabi-v7a", "x86", "x86_64", "arm64-v8a" and other folders, Again open can see is in the LIB prefix so format file, this is the compiled native layer file, we usually refer to the third party library (Baidu map) is also to add these files to our Libs folder, different names represent different platforms related to the compilation of files, Most of the mobile phones on the market are ARM architecture cpu,x86 architecture of the mobile phone almost no one to use (Genymotion simulator belongs to the x86 platform), so we usually release the app does not consider the x86 platform, just add armeabi files can, However, it is recommended to add x86 so files in the development process to facilitate our operation on the simulator.
Run the Library
The Android platform comes with a miniature C Run-time Library Support library that becomes the System runtime library. The runtime does not support features: C standard library, exception support, RTTI support. NDK provides some additional C + + runtime libraries to complement the system runtime functionality.
C + + Runtime library |
C + + exception support |
C++rtti |
C + + standard library |
System Library |
No |
No |
No |
gabi++ |
No |
Yes |
No |
STLport |
No |
Yes |
Yes |
GNU STL |
Yes |
Yes |
Yes |
1.STLportSTLport is an open source, multi-platform C standard library implementation. It provides a complete set of C standard library header files and support for Rtti.
2.GNU STLGNU standard C library, also known as Libstdc-v3, is the most comprehensive standard C Run-time library for Android NDK. It is an open source project that is being developed to achieve the ISO standard C library.
Gradle Configuration
- STL Runtime Reference
- "Armeabi", "armeabi-v7a", "x86", "x86_64", "arm64-v8a" platform configuration
- C + + Output LOGCAT configuration
- A compilation exception resolution
- Exception capture
Generate the name of so file
modulename "Joyrun"
//Introduction STL Standard library
STL "Stlport_static"//gnustl_static
//For solving __android_ Log_print
ldlibs "log"
abifilters "Armeabi", "armeabi-v7a", "x86", "x86_64", "arm64-v8a"//Add compiled platform
//add- Fexceptions to allow throw error
//add-w to "format not a string literal and no format arguments [-WERROR=FORMAT-SECU Rity "
cflags"-w-fexceptions "
Logcat output
#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 ");
Type conversions
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 two values Jni_true, Jni_false
C + + calls Java code
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, param 1-PARAM2));
return param1-param2;
}
C++
Jniexport void Jnicall Java_cn_taoweiji_nativemodule_nativedemo_nativetojava (jnienv * env, Jclass, Jobject obj)
{ c2/>//invokes Java method
Jclass cls = Env->findclass ("Cn/taoweiji/nativemodule/nativedemo");
Jmethodid mid = Env->getmethodid (CLS, "Subtract", "(II) I");
int result = (int) env->callintmethod (obj, Mid, 2);
Common type conversion Examples
//string getInfo ();
-> () ljava/lang/string;
PackageInfo Getpackageinfo (String packagename, int flags);
-> (Ljava/lang/string;i) landroid/content/pm/packageinfo;;
}
One-click to generate script from Java to C + + interface code
File: autojavah.sh
#!/bin/sh
Export projectpath=$ (CD). /$ (dirname "$"); 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} "
Introduction of C + + object-oriented and standard library
C + + class definition
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 * *
Implementation of the class method
Demo.cpp
#include "demo.hpp"
#include <iostream>
void Demo::say ()
{
std::cout<< ' name = ' <<name<< ', age = ' <<age<<std::endl;
}
object to create and access members of an object
object to create a
Demo D1;
Demo * D2 = new Demo;
operator to access
D1.say ();
Pointer access to
D2->say ();
static function Access
int result = Demo::add (1,2);
std::cout<< "1 + 2 =" <<result<<std::endl;
List Chain List
Include related files
#include <stdio.h>
#include <iostream>
#include <list>
#include " DEMO.HPP "
//List definition
std::list<demo> * demos = new std::list<demo>;
Demo * Demo = new Demo;
Demo->name = "Wiki";
Demo->age =;
Insert Data
demos->push_back (*demo) at the back;
Demo = new Demo;
Demo->name = "Wiki2";
Demo->age =;
Insert Data
Demos->push_front (*demo) in front;
Sequential list traversal for
(std::list<demo>::iterator iter = Demos->begin (); Iter!= demos->end (); ++iter) {
Iter->say ();
}
Reverse sequential list traversal for
(std::list<demo>::reverse_iterator iter = Demos->rbegin (); Iter!= demos->rend (); + + ITER) {
iter->say ();
}
Gets the specified location element
std::list<demo>::iterator iter = Demos->begin ();
Advance (ITER, 1);
Iter->say ();
pointers, references, and values
In C + +, functions can pass parameters in many different ways, such as through pointers, references, or direct values.
Through the pointer
void Handle1 (Demo *p);
By referencing
void Handle1 (demo& p);
Through the value
void Handle1 (Demo *demo);
Heap and stack of understanding
Stack: The automatic allocation of the release by the operating system, the value of the parameters of the function, local variables, and so on. The mode of operation is similar to the stack in the data structure;
Heap (heap): typically assigned by programmers to release, if the programmer does not release, the program at the end may be reclaimed by the OS, the distribution is similar to the list.
Demo d1;//Stack
demo * d2 = new demo;//heap
char C;//Stack allocated
char *p = new char[3];//heap allocation, assign address to p;
Garbage collection
The new and C + + DELETE operators are used to dynamically allocate and revoke memory operators, and objects that are new to them release memory by Delete.
Delete demos;
Vi. common methods and precautions in development (PIT)
- Timestamp Fetch method long = time (0);
- Note so file anti-theft problem.
- Try to avoid invoking platform-related methods to avoid problems with porting.
- The package name of the JNI interface cannot be underlined ' _ '.
Related Source code:
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
The above is the C/s + + in the Android and java,objective-c three platforms to develop the application of data collation, follow-up to continue to organize related articles, thank you for your support of this site!