0

I'm trying to use a python interpreter in my Android app to run SymPy. I already compiled Python for arm using this guide. http://mdqinc.com/blog/2011/09/cross-compiling-python-for-android/

This got me a libpython2.7.so file which I put into jniLibs/armeabi/. In my app I load it as follows:

public class PythonTest {
    static {
        System.loadLibrary("python2.7");
    }

    public static native void Py_Initialize();
    public static native void Py_Finalize();
    public static native int PyRun_SimpleString(String s);
}

I am trying to use the methods from the headers located in the include directory which can also be found here: https://docs.python.org/2/c-api/

When I run the app on my device I get the following error:

No implementation found for void com.example.dorian.testapplication.PythonTest.Py_Initialize() (tried Java_com_example_dorian_testapplication_PythonTest_Py_1Initialize and Java_com_example_dorian_testapplication_PythonTest_Py_1Initialize__)

So to me this seems like the library loaded but it seems to look for the JNIEXPORT functions. But shouldn't I be able to use this library without writing specific C++ files? And if not, how would I accomplish this. Might there be a tool to generate wrapper files or something similar?

D0r1an
  • 36
  • 5

1 Answers1

0

You need a JNI wrapper lib that will serve as a bridge between your Java code and libpython2.7.so. It may be enough for straters to have the three functions wrapped according to the JNI convention, e.g.

JNIEXPORT jint JNICALL com_example_dorian_testapplication_PythonTest_PyRun_1SimpleString
  (JNIEnv *env, jclass jc, jstring js)
{
    char* cs = env->GetStringUTFChars(js, 0);
    std::string s = new std::string(cs);
    env->ReleaseStringUTFChars(env, js, cs);
    return PyRun_SimpleString(s.c_str());
}

If something is not clear, please read the tutorial at http://joaoventura.net/blog/2014/python-android-2.

Note that you can use any package name for the PythonTest class, not necessarily related to your Android app package name, e.g.

package com.python27;
class Python {
static {
    System.loadLibrary("python2.7");
}

public static native void Initialize();
public static native void Finalize();
public static native int Run(String s);
}

will expect the JNI wrappers

JNIEXPORT void JNICALL com_python27_Python_Initialize(JNIEnv *env, jclass jc);
JNIEXPORT void JNICALL com_python27_Python_Finalize(JNIEnv *env, jclass jc);
JNIEXPORT jint JNICALL com_python27_Python_Run(JNIEnv *env, jclass jc, jstring js);
Alex Cohn
  • 56,089
  • 9
  • 113
  • 307