如何在 android 中使用 .so 库
How to use .so library in android
我正在尝试在我的 Android 应用程序中使用 python 解释器来访问 运行 SymPy。我已经使用本指南为 arm 编译了 Python。 http://mdqinc.com/blog/2011/09/cross-compiling-python-for-android/
这给了我一个 libpython2.7.so 文件,我将其放入 jniLibs/armeabi/。
在我的应用程序中,我按如下方式加载它:
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);
}
我正在尝试使用位于 include 目录中的 headers 中的方法,该目录也可以在这里找到:https://docs.python.org/2/c-api/
当我 运行 我的设备上的应用程序出现以下错误:
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__)
所以对我来说,这似乎是加载了库,但它似乎在寻找 JNIEXPORT 函数。但是我不应该在不编写特定 C++ 文件的情况下使用这个库吗?如果没有,我将如何做到这一点。可能有生成包装文件或类似文件的工具吗?
您需要一个 JNI 包装器库,它将作为您的 Java 代码和 libpython2.7.so 之间的桥梁。对于战略人员来说,根据 JNI 约定将三个函数包装起来可能就足够了,例如
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());
}
如果有什么不清楚的地方,请阅读 http://joaoventura.net/blog/2014/python-android-2 上的教程。
请注意,您可以为 PythonTest class 使用任何包名称,不一定与您的 Android 应用程序包名称相关,例如
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);
}
需要 JNI 包装器
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);
我正在尝试在我的 Android 应用程序中使用 python 解释器来访问 运行 SymPy。我已经使用本指南为 arm 编译了 Python。 http://mdqinc.com/blog/2011/09/cross-compiling-python-for-android/
这给了我一个 libpython2.7.so 文件,我将其放入 jniLibs/armeabi/。 在我的应用程序中,我按如下方式加载它:
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);
}
我正在尝试使用位于 include 目录中的 headers 中的方法,该目录也可以在这里找到:https://docs.python.org/2/c-api/
当我 运行 我的设备上的应用程序出现以下错误:
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__)
所以对我来说,这似乎是加载了库,但它似乎在寻找 JNIEXPORT 函数。但是我不应该在不编写特定 C++ 文件的情况下使用这个库吗?如果没有,我将如何做到这一点。可能有生成包装文件或类似文件的工具吗?
您需要一个 JNI 包装器库,它将作为您的 Java 代码和 libpython2.7.so 之间的桥梁。对于战略人员来说,根据 JNI 约定将三个函数包装起来可能就足够了,例如
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());
}
如果有什么不清楚的地方,请阅读 http://joaoventura.net/blog/2014/python-android-2 上的教程。
请注意,您可以为 PythonTest class 使用任何包名称,不一定与您的 Android 应用程序包名称相关,例如
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);
}
需要 JNI 包装器
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);