android jni程序(c++)如何编译适用于arm-v8指令集的32位程序

APP_ABI该如何制定?我制定成arm64-v8a后,编译时就不调用我指定的4.8版本的arm-linux-androideabi-gcc了,而是会调用一个64位编译器... APP_ABI该如何制定?我制定成arm64-v8a后,编译时就不调用我指定的4.8版本的arm-linux-androideabi-gcc了,而是会调用一个64位编译器,我该如何编译32位的?
另外海思的hi3751-v600 cpu是armv8指令集的,是否完全兼容armv7a的程序,我的android jni程序在以前的设备上跑的好好的,在海思这款芯片上一跑就crash在了boost库里面,这是不兼容吗
展开
 我来答
百度网友4327fcbb9b
2015-07-27 · 知道合伙人教育行家
百度网友4327fcbb9b
知道合伙人教育行家
采纳数:26422 获赞数:292078
从师范学校毕业后一直在现在单位工作

向TA提问 私信TA
展开全部
  可以看到Android上层的Application和ApplicationFramework都是使用Java编写,

底层包括系统和使用众多的LIiraries都是C/C++编写的。

  所以上层Java要调用底层的C/C++函数库必须通过Java的JNI来实现。

下面将学习Android是如何通过Jni来实现Java对C/C++函数的调用。以HelloWorld程序为例:

第一步:

使用Java编写HelloWorld 的Android应用程序:

package com.lucyfyr;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class HelloWorld extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  Log.v("dufresne", printJNI("I am HelloWorld Activity"));
}
  static
  {
    //加载库文件
    System.loadLibrary("HelloWorldJni");
  }
  //声明原生函数 参数为String类型 返回类型为String
  private native String printJNI(String inputStr);
}

  这一步我们可以使用eclipse来生成一个App;

因为eclipse会自动为我们编译此Java文件,后面要是用到。

第二步:

  生成共享库的头文件:

  进入到eclipse生成的Android Project中 :/HelloWorld/bin/classes/com/lucyfyr/
下:

  可以看到里面后很多后缀为.class的文件,就是eclipse为我们自动编译好了的java文件,其中就有:

    HelloWorld.class文件。

  退回到classes一级目录:/HelloWorld/bin/classes/

执行如下命令:

  javah com.lucyfyr.HelloWorld

  生成文件:com_lucyfyr_HelloWorld.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_lucyfyr_HelloWorld */
#ifndef _Included_com_lucyfyr_HelloWorld
#define _Included_com_lucyfyr_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_lucyfyr_HelloWorld
* Method: printJNI
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI
(JNIEnv *, jobject, jstring);
#ifdef __cplusplus
}
#endif
#endif

  可以看到自动生成对应的函数:Java_com_lucyfyr_HelloWorld_printJNI

    Java_ + 包名(com.lucyfyr) + 类名(HelloWorld) + 接口名(printJNI):必须要按此JNI规范来操作;

  java虚拟机就可以在com.simon.HelloWorld类调用printJNI接口的时候自动找到这个C实现的Native函数调用。

  当然函数名太长,可以在.c文件中通过函数名映射表来实现简化。

第三步:

实现JNI原生函数源文件:

新建com_lucyfyr_HelloWorld.c文件:

#include <jni.h>
#define LOG_TAG "HelloWorld"
#include <utils/Log.h>
/* Native interface, it will be call in java code */
JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI(JNIEnv *env, jobject obj,jstring inputStr)
{
  LOGI("dufresne Hello World From libhelloworld.so!");
  // 从 instring 字符串取得指向字符串 UTF 编码的指针
  const char *str =
  (const char *)(*env)->GetStringUTFChars( env,inputStr, JNI_FALSE );
  LOGI("dufresne--->%s",(const char *)str);
  // 通知虚拟机本地代码不再需要通过 str 访问 Java 字符串。
  (*env)->ReleaseStringUTFChars(env, inputStr, (const char *)str );
  return (*env)->NewStringUTF(env, "Hello World! I am Native interface");
}
/* This function will be call when the library first be load.
* You can do some init in the libray. return which version jni it support.
*/
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
  void *venv;
  LOGI("dufresne----->JNI_OnLoad!");
  if ((*vm)->GetEnv(vm, (void**)&venv, JNI_VERSION_1_4) != JNI_OK) {
    LOGE("dufresne--->ERROR: GetEnv failed");
    return -1;
  }
  return JNI_VERSION_1_4;
}

  OnLoadJava_com_lucyfyr_HelloWorld_printJNI

函数里面做一些log输出 注意JNI中的log输出的不同。

  JNI_OnLoad函数JNI规范定义的,当共享库第一次被加载的时候会被回调,

这个函数里面可以进行一些初始化工作,比如注册函数映射表,缓存一些变量等,

最后返回当前环境所支持的JNI环境。本例只是简单的返回当前JNI环境。

http://www.cnblogs.com/bastard/archive/2012/05/19/2508913.html
追问
请你不要扯淡好吗
追答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式