今天终于把NDK库编译过去了。。。(库调另外一个库)
最主要的难点就是,原生库是调用的c++方法,所以在我生成的com_sunniwell_NDK_Jni.c文件要改成com_sunniwell_NDK_Jni.cpp。同时修改JNIEnv* env调用方法的几个参数问题(和c不同)。这样,在编译的时候才能编译过去。 还有就是,如果库依赖另外的原生库,那些原生库还是尽量要重新编译。同时,导入库后把盒子再重启。
编译环境:ubuntu 10.10 +elipse_android开发环境+android 4.0源码.
这里我把整个编译过程简约的写一下:
1,建立一个android项目,项目名为standard,注意包名为com.sunniwell.NDK. 因为这个包名和项目名后面要用到。
</br>2,编写Jni.java文件。
内容如下:
package com.sunniwell.NDK; //注意包名:com.sunniwell.NDK
public class Jni {
public native int displayStandard(String mode);
public native int displayPosition(int w, int h, int x, int y);
}
</br>3,复制Jni.java文件到到 standard /bin/目录下。
</br>4,调用命令窗口,进入 standard /bin/目录下,输入命令:javac Jni.java.这样会在该目录下生成:Jni.class。把该文件复制到 standard/bin/com/sunniwell/NDK/目录下,覆盖原来的Jni.class。
</br>5,再次回到standard/bin目录。输入命令:javah -jni com.sunniwell.NDK.Jni
。这样会在standard/bin目录下生成:com_sunniwell_NDK_Jni.h文件。
内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_sunniwell_NDK_Jni */
#ifndef _Included_com_sunniwell_NDK_Jni
#define _Included_com_sunniwell_NDK_Jni
#ifdef __cplusplus
extern "C"
{
#endif
/*
* Class: com_sunniwell_NDK_Jni
* Method: displayStandard
* Signature: (Ljava/lang/String;)I
*/
JNIEXPORT jint JNICALL
Java_com_sunniwell_NDK_Jni_displayStandard(JNIEnv *, jobject, jstring);
/*
* Class: com_sunniwell_NDK_Jni
* Method: displayPosition
* Signature: (IIII)I
*/
JNIEXPORT jint JNICALL
Java_com_sunniwell_NDK_Jni_displayPosition(JNIEnv *, jobject, jint, jint, jint, jint);
#ifdef __cplusplus
}
#endif
#endif
</br>6,创建com_sunniwell_NDK_Jni.cpp文件。(因为原生库中的实现是用c++实现的,所以我们这里要创建.cpp文件)内容如下:
#include <stdio.h>
#include <stdlib.h>
#inlcude <string.h>
#include <com_sunniwell_NDK_Jni.h>
#include "standard.h"
JNIEXPORT jint JNICALL
java_com_sunniwell_NDK_Jni_displayStandard(JNIEnv *env, jobject thiz, jstring mode)
{
const char* modeStr = env->GetStringUTFChars(mode, NULL);
//如果这是.c文件。这里就要这样写
//const char* modeStr = (*env)->GetStringUTFChars(env, mode, NULL);同理下面的env实现的函数都要这样写
char* buf = (char *)malloc(strlen(modeStr) +1);
memset(buf, 0, strlen(modeStr)+1);
strcpy(buf, modeStr);
//这里是实现const char* 转换为char*
env->ReleaseStringUTFChars(mode, modeStr);
return sw_display_change_standard(buf);
}
JNIEXPORT jint JNICALL
java_com_sunniwell_NDK_Jni_displayPosition(JNIEnv *env, jobject thiz, jint w, jint h, jint x, jint y)
{
return sw_display_panel_position(w,h,x,y);
}
</br>7,然后再写个Android.mk文件。内容入下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libstand
LOCAL_MODULE_TAGS := optional
LOCAL_CERTIFICATE := platform
LOCAL_C_INCLUDES := \
$(JNI_H_INCLUDE)
LOCAL_SRC_FILES := \
com_sunniwell_NDK_Jni.cpp
LOCAL_PRELINK_MODULE := false
LOCAL_SHARED_LIBRARIES := \
libswstandard
include $(BUILD_SHARED_LIBRARY)
这样,在当前目录下输入mm编译就可以了。这样会在out/target/product/vortex/system/lib
目录下生成libstand。这个就是我们应用程序中要用到得库.