在 android studio JNI 函数中使用 jint 和 jstring
using jint and jstring in android studio JNI function
我正在 Android Studio 中开发一个 JNI 示例,目标是生成一个随机值并将其传递给一个本地函数,该函数将计算其平方和 return 结果这种格式 ( Number/Square ).
我将 jint 编号作为函数的参数传递,但结果完全错误(显示的结果完全错误)。
这是我的代码:
按钮生成数字并调用本机函数:
Button ButtonP = (Button)findViewById(R.id.button3);
ButtonP .setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
Random r = new Random();
Integer valeur = 1 + r.nextInt(10 - 1);
Log.i("Tag", "Random Value BARRAK " + valeur);
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(stringFromJNIStop(valeur));
}
});
原生函数:
public native String stringFromJNIStop(Integer nombre);
cpp文件中函数的实现:
extern "C"
JNIEXPORT jstring JNICALL
Java_fr_utbm_testjniapplication1_MainActivity_stringFromJNIStop(
JNIEnv *env,
jobject, /* this */
jint nombre) {
jint CarreNombre = nombre*nombre;
//Convertir le carré en un jstring
char bufCarreNombre[64];
sprintf(bufCarreNombre, "%d", CarreNombre); // error checking omitted
jstring jStringCarre = (*env).NewStringUTF(bufCarreNombre);
//Le convertir en un char *
const char *strCarre= (*env).GetStringUTFChars(jStringCarre,0);
//Convertir le nombre en un jstring
char bufNombre[64];
sprintf(bufNombre, "%d", nombre); // error checking omitted
jstring jStringNombre = (*env).NewStringUTF(bufNombre);
//Le convertir en char *
const char *strNombre= (*env).GetStringUTFChars(jStringNombre,0);
//Concaténer les deux
char *concatenated;
concatenated = (char *) malloc(strlen(strNombre) + strlen("/") + strlen(strCarre) + 1);
strcpy(concatenated, strNombre);
strcat(concatenated, "/");
strcat(concatenated, strCarre);
/* Create java string from our concatenated C string */
jstring retval = (*env).NewStringUTF(concatenated);
//need to release this string when done with it in order to
//avoid memory leak
(*env).ReleaseStringUTFChars(jStringNombre,strNombre);
(*env).ReleaseStringUTFChars(jStringCarre,strCarre);
/* Free the memory in concatenated */
free(concatenated);
return retval;
}
经过一番反思,问题解决了,实际上为了使用jint实现JNI功能,我们必须在JAVA部分采用精确的转换规则,而不是声明随机值作为整数,我们必须将其声明为 long !所以我们必须按如下方式工作:
long valeur = 1 + r.nextInt(10 - 1);
The Native function:
public native String stringFromJNIStop(Integer nombre);
The implementation of the function in the cpp file:
extern "C"
JNIEXPORT jstring JNICALL
Java_fr_utbm_testjniapplication1_MainActivity_stringFromJNIStop(
JNIEnv *env,
jobject, /* this */
jint nombre) {
这与您的 Java 不一致。您在 Java 中将它从 int
更改为 Integer
而没有重新生成您的 .h 文件,或者您更改或发明了您的 .h 文件而没有参考您的 .java 文件;或者您的 .cpp 文件与您的 .h/.hpp 文件不一致。不要这样做。使用 javah
生成您的 .h/.hpp 文件,并在每次更改 .java 文件中的本地声明时重做,并确保您的 .cpp 文件与 .cpp 文件一致。 h/.hpp 文件。应该是:
extern "C"
JNIEXPORT jstring JNICALL
Java_fr_utbm_testjniapplication1_MainActivity_stringFromJNIStop(
JNIEnv *env,
jobject, /* this */
jobject nombre) {
其中 nombre
指的是 Integer
。然而,将您的 Java 本机方法定义为:
会更好,而且总是会更好
public native String stringFromJNIStop(int nombre);
现在将与您现有的 .cpp 一致。
您的 .cpp 也应该 #include
您的 .h/.hpp。那么您就不需要 extern "C"
或 JNI_EXPORT
或 JNI_CALL
,并且编译器可能已经检测到 .cpp 和 .h/.hpp 之间的签名不一致。
我正在 Android Studio 中开发一个 JNI 示例,目标是生成一个随机值并将其传递给一个本地函数,该函数将计算其平方和 return 结果这种格式 ( Number/Square ).
我将 jint 编号作为函数的参数传递,但结果完全错误(显示的结果完全错误)。 这是我的代码:
按钮生成数字并调用本机函数:
Button ButtonP = (Button)findViewById(R.id.button3);
ButtonP .setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
Random r = new Random();
Integer valeur = 1 + r.nextInt(10 - 1);
Log.i("Tag", "Random Value BARRAK " + valeur);
TextView tv = (TextView) findViewById(R.id.sample_text);
tv.setText(stringFromJNIStop(valeur));
}
});
原生函数:
public native String stringFromJNIStop(Integer nombre);
cpp文件中函数的实现:
extern "C"
JNIEXPORT jstring JNICALL
Java_fr_utbm_testjniapplication1_MainActivity_stringFromJNIStop(
JNIEnv *env,
jobject, /* this */
jint nombre) {
jint CarreNombre = nombre*nombre;
//Convertir le carré en un jstring
char bufCarreNombre[64];
sprintf(bufCarreNombre, "%d", CarreNombre); // error checking omitted
jstring jStringCarre = (*env).NewStringUTF(bufCarreNombre);
//Le convertir en un char *
const char *strCarre= (*env).GetStringUTFChars(jStringCarre,0);
//Convertir le nombre en un jstring
char bufNombre[64];
sprintf(bufNombre, "%d", nombre); // error checking omitted
jstring jStringNombre = (*env).NewStringUTF(bufNombre);
//Le convertir en char *
const char *strNombre= (*env).GetStringUTFChars(jStringNombre,0);
//Concaténer les deux
char *concatenated;
concatenated = (char *) malloc(strlen(strNombre) + strlen("/") + strlen(strCarre) + 1);
strcpy(concatenated, strNombre);
strcat(concatenated, "/");
strcat(concatenated, strCarre);
/* Create java string from our concatenated C string */
jstring retval = (*env).NewStringUTF(concatenated);
//need to release this string when done with it in order to
//avoid memory leak
(*env).ReleaseStringUTFChars(jStringNombre,strNombre);
(*env).ReleaseStringUTFChars(jStringCarre,strCarre);
/* Free the memory in concatenated */
free(concatenated);
return retval;
}
经过一番反思,问题解决了,实际上为了使用jint实现JNI功能,我们必须在JAVA部分采用精确的转换规则,而不是声明随机值作为整数,我们必须将其声明为 long !所以我们必须按如下方式工作:
long valeur = 1 + r.nextInt(10 - 1);
The Native function:
public native String stringFromJNIStop(Integer nombre);
The implementation of the function in the cpp file:
extern "C"
JNIEXPORT jstring JNICALL
Java_fr_utbm_testjniapplication1_MainActivity_stringFromJNIStop(
JNIEnv *env,
jobject, /* this */
jint nombre) {
这与您的 Java 不一致。您在 Java 中将它从 int
更改为 Integer
而没有重新生成您的 .h 文件,或者您更改或发明了您的 .h 文件而没有参考您的 .java 文件;或者您的 .cpp 文件与您的 .h/.hpp 文件不一致。不要这样做。使用 javah
生成您的 .h/.hpp 文件,并在每次更改 .java 文件中的本地声明时重做,并确保您的 .cpp 文件与 .cpp 文件一致。 h/.hpp 文件。应该是:
extern "C"
JNIEXPORT jstring JNICALL
Java_fr_utbm_testjniapplication1_MainActivity_stringFromJNIStop(
JNIEnv *env,
jobject, /* this */
jobject nombre) {
其中 nombre
指的是 Integer
。然而,将您的 Java 本机方法定义为:
public native String stringFromJNIStop(int nombre);
现在将与您现有的 .cpp 一致。
您的 .cpp 也应该 #include
您的 .h/.hpp。那么您就不需要 extern "C"
或 JNI_EXPORT
或 JNI_CALL
,并且编译器可能已经检测到 .cpp 和 .h/.hpp 之间的签名不一致。