NDK JAVA / C++ (great!!)

fabiodelorenzo
Posts: 65
Joined: Thu Oct 03, 2013 5:54 pm

NDK JAVA / C++ (great!!)

Postby fabiodelorenzo » Mon Jan 11, 2016 12:37 am

as for the C example,

define your classes in jni/example.h

Code: Select all

/* File : example.h */

class Shape {
public:
  Shape() {
    nshapes++;
  }
  virtual ~Shape() {
    nshapes--;
  };
  double  x, y;   
  void    move(double dx, double dy);
  virtual double area(void) = 0;
  virtual double perimeter(void) = 0;
  static  int nshapes;
};

class Circle : public Shape {
private:
  double radius;
public:
  Circle(double r) : radius(r) { };
  virtual double area(void);
  virtual double perimeter(void);
};

class Square : public Shape {
private:
  double width;
public:
  Square(double w) : width(w) { };
  virtual double area(void);
  virtual double perimeter(void);
};



and the implementation in jni/example.cpp

Code: Select all

/* File : example.cpp */

#include "example.h"
#define M_PI 3.14159265358979323846

/* Move the shape to a new location */
void Shape::move(double dx, double dy) {
  x += dx;
  y += dy;
}

int Shape::nshapes = 0;

double Circle::area(void) {
  return M_PI*radius*radius;
}

double Circle::perimeter(void) {
  return 2*M_PI*radius;
}

double Square::area(void) {
  return width*width;
}

double Square::perimeter(void) {
  return 4*width;
}



Create a SWIG interface file for this C++ code in jni/example.i:

Code: Select all

/* File : example.i */
%module example

%{
#include "example.h"
%}

/* Let's just grab the original header file here */
%include "example.h"


NOTE: the classes are not defined in the SWIG file but only the header file is exposed. The module is called example

Invoke SWIG as follows, note that the -c++ option is required for C++ code:

Code: Select all

$ swig -c++ -java -package org.swig.classexample -outdir src/org/swig/classexample -o jni/example_wrap.cpp jni/example.i


SWIG generates the following files:

Code: Select all

    src/org/swig/classexample/Square.java
    src/org/swig/classexample/exampleJNI.java
    src/org/swig/classexample/example.java
    src/org/swig/classexample/Circle.java
    src/org/swig/classexample/Shape.java
    jni/example_wrap.cpp



Create the makefile to build the C++ in jni/Android.mk:

Code: Select all

# File: Android.mk
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := example
LOCAL_SRC_FILES := example_wrap.cpp example.cpp
LOCAL_CFLAGS    := -frtti

include $(BUILD_SHARED_LIBRARY)


build the code:
$ ndk-build
Compile++ thumb : example <= example_wrap.cpp
Compile++ thumb : example <= example.cpp
StaticLibrary : libstdc++.a
SharedLibrary : libexample.so
Install : libexample.so => libs/armeabi/libexample.so



Now, let's use those classes from the java:

Code: Select all

 /** Calls into C/C++ code */
    public void nativeCall()
    {
      // ----- Object creation -----
      Circle c = new Circle(10);
      outputText.append( "    Created circle " + c + "\n");
      Square s = new Square(10);
      outputText.append( "    Created square " + s + "\n");

      // ----- Access a static member -----
      outputText.append( "\nA total of " + Shape.getNshapes() + " shapes were created\n" );

      // ----- Member data access -----
      // Notice how we can do this using functions specific to the 'Circle' class.
      c.setX(20);
      c.setY(30);

      // Now use the same functions in the base class
      Shape shape = s;
      shape.setX(-10);
      shape.setY(5);

      // ----- Call some methods -----
      Shape[] shapes = {c,s};
      for (int i=0; i<shapes.length; i++)
      {
        outputText.append( "   " + shapes[i].toString() + "\n" );
        outputText.append( "        area      = " + shapes[i].area() + "\n" );
        outputText.append( "        perimeter = " + shapes[i].perimeter() + "\n" );
      }

      // Notice how the area() and perimeter() functions really
      // invoke the appropriate virtual method on each object.

      // ----- Delete everything -----
      // Note: this invokes the virtual destructor. You could leave this to the garbage collector
      c.delete();
      s.delete();
    }

    /** static constructor */
    static {
        System.loadLibrary("example");
    }



NB: if you are using STL in C++:

Should the C++ Standard Template Library (STL) be required, an Application.mk file needs to be created in the same directory as the Android.mk directory containing information about the STL to use.
See the NDK documentation in the $NDKROOT/docs folder especially CPLUSPLUS-SUPPORT.html.

Below is an example of the Application.mk file to make the STLport static library available for use:

# File: Application.mk
APP_STL := gnustl_static

Return to “NDK and low level AOSP”

Who is online

Users browsing this forum: No registered users and 1 guest