【问题标题】:Android JNI - String return as random numberAndroid JNI - 字符串作为随机数返回
【发布时间】:2016-06-24 06:20:01
【问题描述】:

我是 JNI 和 Android 的新手。我想从本机代码返回一个字符串值,但它在执行时返回一些随机数。我无法理解我做错了什么。

我的“ndk.c”文件:

int Java_com_example_mayankvijh_test_1app_MainActivity_main(){
return 3;
}

jstring JNICALL Java_com_example_mayankvijh_test_1app_MainActivity_getMessage(JNIEnv *env, jobject thiz) {
  return (*env)->NewStringUTF(env,"HELLO");
  }

我的 MainActivity.java

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    try{
        System.loadLibrary("wrapper");

    }catch(Exception e)
    {
        e.printStackTrace();
    }

    System.out.println("main return =" + main());
    System.out.println("Hi " + getMessage());
}

public native int main();
public native int getMessage();

我已成功加载库(“.so”),我能够返回类型 jint 并显示在应用程序中,但不知何故 jstring 返回随机数。

我的原生 main 函数正在返回 int 并且正在工作,但是对于我的 getMessage() 函数,字符串没有返回

getMessage() 的输出:

Hi -429916127

我的应用程序.mk

APP_ABI := armeabi-v7a
APP_PLATFORM := android-9

我的 Android.mk

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := wrapper

LOCAL_C_INCLUDES := $(LOCAL_PATH)

LOCAL_SRC_FILES := ndk.c

LOCAL_LDLIBS := -landroid
#--llog -lz

include $(BUILD_SHARED_LIBRARY)

感谢您的帮助。

【问题讨论】:

  • 使用jobject thiz 而不是jclass cls 参考这个developer.android.com/ndk/samples/sample_hellojni.html
  • 我都试过了,它返回的是随机负数。目前它返回'Hi -253755359'
  • JNIEXPORT 删除这个关键字。
  • 现在它返回正数 'Hi 97517601' 但不是字符串

标签: java android c java-native-interface


【解决方案1】:

您有冲突的返回类型:

jstring JNICALL Java_com_example_mayankvijh_test_1app_MainActivity_getMessage(JNIEnv *env, jobject thiz) {
  return (*env)->NewStringUTF(env,"HELLO");
  }

public native int getMessage();

指针,在本机代码中返回,被视为整数。您应该将 java 中的声明修复为:

public native String getMessage();

【讨论】:

  • 天哪,我从来没有注意到,我在本机端更改了一个方法,但忘记在 java 端更改它。愚蠢的菜鸟错误。非常感谢
【解决方案2】:

Java 端:

  public class HelloJni extends Activity{

 @Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);  
    TextView  tv = new TextView(this);
    tv.setText( stringFromJNI() );
    setContentView(tv);
}

public native String  stringFromJNI();
public native String  unimplementedStringFromJNI();  
static {
    System.loadLibrary("hello-jni");
  }
 }

Native Side:文件名hello-jni.c

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

/* This is a trivial JNI example where we use a native method
 * to return a new VM String. See the corresponding Java source
 * file located at:
 *
 *   apps/samples/hello-jni/project/src/com/example/hellojni/HelloJni.java
 */
jstring
Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,
                                                  jobject thiz )
{
#if defined(__arm__)
  #if defined(__ARM_ARCH_7A__)
    #if defined(__ARM_NEON__)
      #if defined(__ARM_PCS_VFP)
        #define ABI "armeabi-v7a/NEON (hard-float)"
      #else
        #define ABI "armeabi-v7a/NEON"
      #endif
    #else
      #if defined(__ARM_PCS_VFP)
        #define ABI "armeabi-v7a (hard-float)"
      #else
        #define ABI "armeabi-v7a"
      #endif
    #endif
  #else
   #define ABI "armeabi"
  #endif
#elif defined(__i386__)
   #define ABI "x86"
#elif defined(__x86_64__)
   #define ABI "x86_64"
#elif defined(__mips64)  /* mips64el-* toolchain defines __mips__ too */
   #define ABI "mips64"
#elif defined(__mips__)
   #define ABI "mips"
#elif defined(__aarch64__)
   #define ABI "arm64-v8a"
#else
   #define ABI "unknown"
#endif

    return (*env)->NewStringUTF(env, "Hello from JNI !  Compiled with ABI " ABI ".");
}

更新:

jstring JNICALL Java_com_example_mayankvijh_test_1app_MainActivity_getMessage(JNIEnv *env, jobject thiz) {
return  (*env)->NewStringUTF(env,"HELLO");
}

【讨论】:

  • 两者都试过了,它返回一个随机数。只是补充一下,我可以在使用和不使用'JNIEXPORT'的情况下返回int
  • @MayankVijh 你是否像上面那样尝试
  • 请检查编辑。我觉得和你说的一样。我正在创建一个“wrapper.so”并使用它。
  • 将你的 android.mk 文件发布到 jni 文件夹中
  • 如果你找不到它发布你的应用程序的 gradle 文件
猜你喜欢
  • 1970-01-01
  • 2020-04-29
  • 2020-06-16
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
  • 2011-11-15
相关资源
最近更新 更多