我有一个库说 libraryOne.so (File1.c)包含纯C代码。 现在我想从我的Java文件中访问此代码。为此,我将使用标准的JNI程序。 但是对于使用JNI,我还应该修改File1.c中的C代码(比如包含JNI的头文件和一些标准的JNIEXPORT东西)。 所以我正在创建一个包装器库( libraryWrapper.so 由File2.c制作)。 此库将包含所需的JNI声明,并且应与我的Java文件交互。 现在我想知道如何从File2.c中调用File1.c的纯C函数
答案 0 :(得分:0)
首先,您应该阅读ndk-tutorial。因为你需要设置ndk等等。之后你可以寻找ndk样本来学习如何做事。如何建立
实际上,上面是你的回答。 来到你的问题。
您应该拥有libraryOne.so的源代码。正如你所说的那样。导致android目标很多平台上你无法运行。所以它需要用ndk编译
确定让我们的文件为File1.c
int myfunction(const char* st){
int answer=0;
//stufs here
return answer;
}
首先,添加我们想要访问的Java类
package example.com.myapplication;
public class JniClass {
static {
System.loadLibrary("libraryWrapper");
}
public native int myFunction(String a );
}
现在我们需要包装器。为此我们应该知道jni接口。幸运的是,有一个名为javah的工具可以为我们生成它,并且可以避免我们为所有调用手动执行此操作。 我们应该构建我们的android项目,以便生成类文件。 我使用debug构建它,所以我生成的文件将在这个/ app / build / intermediates / classes / debug文件夹中。
好的,我们运行javah
javah -jni example.com.myapplication.JniClas
Š
如果你有错误,请参阅Javah error while using it in JNI
它生成了名为example_com_myapplication_JniClass.h
的头文件,其中包含
#include <jni.h>
/* Header for class example_com_myapplication_JniClass */
#ifndef _Included_example_com_myapplication_JniClass
#define _Included_example_com_myapplication_JniClass
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: example_com_myapplication_JniClass
* Method: myFunction
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL Java_example_com_myapplication_JniClass_myFunction
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif
现在好了你的回答。 简单的方法是复制生成的代码并将其粘贴到File1.c代码的底部。并实施它: 请注意,在粘贴它并清理注释后,我将参数命名为env,obj和str
//..here your File1.c source code content
//
#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_example_com_myapplication_JniClass_myFunction
(JNIEnv * env, jobject obj, jstring str){
const char * x=(*env)->GetStringUTFChars(env,str,0);
//call our function
int ret= myfunction(x);
(*env)->ReleaseStringUTFChars(env,str, x);
return ret;
}
#ifdef __cplusplus
}
#endif
但实际上你可能会在c代码上使用头文件。 例如,您可以添加生成的头文件并在.c文件上实现它。在.c文件中,您可以包含File1.c标头。这种方式更干净。
假设您已经阅读了ndk教程。您设置了ndk工具并知道如何构建
最后我们将File1.c添加到jni文件夹并更改Android.mk文件
LOCAL_MODULE:= libraryWrapper LOCAL_SRC_FILES:= File1.c 和
APP_MODULES:= libraryWrapper
然后我们用ndk-build构建它,它将我们的so文件添加到libs
Op只需要File1.c和File2.c 在File2.c中
//declaration of funtions inside File1.c
extern int myfunction(const char* st);
#include <jni.h>
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jint JNICALL Java_example_com_myapplication_JniClass_myFunction
(JNIEnv * env, jobject obj, jstring str){
const char * x=(*env)->GetStringUTFChars(env,str,0);
//call our function
int ret= myfunction(x);
(*env)->ReleaseStringUTFChars(env,str, x);
return ret;
}
#ifdef __cplusplus
}
#endif
并更改Android.mk
LOCAL_SRC_FILES := File1.c
LOCAL_SRC_FILES += File2.c