NDK库编译

今天终于把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。这个就是我们应用程序中要用到得库.

点赞