Kotlin, NDK and C++ interactions

2019-01-27 08:49发布

问题:

I'm not familiar with the Android NDK and I need help to build a Kotlin application using native part of code written in C++. I've found HelloWorld sample using a basic C function but no examples or tutorial using C++ objects.

Let's say I have a C++ object, with hpp and cpp file:

object.hpp

#ifdef object_hpp
#define object_hpp
//
// include part
//

class Object {
  // some stuff
}
#endif

object.cpp

#include "object.hpp"

Object::Object()
{
  //constructor
}

std::string Object::sayHello(std::string value)
{
  // do stuff
}

I want to know what is the best way to use it in a Kotlin app:

  • must I generate first a library (.so or .a ?) and import it into my app ? If so, is there anything to change in the C++ code ?
  • can I import these C++ files into my project (with C++ support, I know it) ? If yes, how can I use it ?

I've read about JNIEXPORT and Java_my_package_name_SomeClass_someMethod() but I'm not sure how to use it: do I need to modify the C++ code itself or should I develop a wrapper to it ?

Many thanks in advance for your help.

回答1:

Ok, thanks to @Richard, here is my wrapper

ObjectWrapper.kt

Exposes the API I want to use. The keyword external of the method indicates that the body is elsewhere. In my case, in the native layer of the wrapper.

class ObjectWrapper {

    companion object {
        init {
            System.loadLibrary("mylibrary")
        }
    }

    external fun sayHello(name: String): String
}

MyLibrary.cpp

Same API as the kotlin part but the methods are named with the completed package name. Here, I have to the translation between the kotlin world and the native world.

#include <jni.h>
#include <string>
#include "Object.h"

static Object *pObject = NULL;

extern "C" {
    JNIEXPORT jstring Java_com_packagename_ObjectWrapper_sayHello(
            JNIEnv *env,
            jobject /* this */,
            jstring input) {
        pObject = new Object();
        const char *msg = env->GetStringUTFChars(input, JNI_FALSE);
        std::string hello = pObject->getHelloString(msg);
        return env->NewStringUTF(hello.c_str());
    }
}