jni生成so动态库,a静态库,传递中文字符串

来源:互联网 发布:人卫版第八版教材知乎 编辑:程序博客网 时间:2024/06/03 23:40

本项目是生成静态库libA.a,用libA.a生成libB.a,再用libA.a和libB.a一起生成libC.so动态库。

1.新建一个安卓项目,添加文件夹jni,在jni下添加cpp或者c文件,此cpp或c文件就是用来生成so的源文件。

2.要生成静态库libA.a,要有Android.mk文件和Application.mk,直接在jni目录下添加即可。

Android.mk内容如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := A//生成的静态库的名字,即libA.a中的ALOCAL_SRC_FILES :=  //需要的源文件,依次列开,用空格或tab隔开include $(BUILD_STATIC_LIBRARY)//生成静态库

Application.mk内容如下:

APP_MODULES :=A//表明生成静态库的名字

3.用静态库libA.a生成libB.a,直接在jni目录下添加Android.mk和Application.mk文件。

Android.mk内容如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS) LOCAL_MODULE    := A LOCAL_SRC_FILES := libA.a include $(PREBUILT_STATIC_LIBRARY) //连接方式是静态的include $(CLEAR_VARS)LOCAL_MODULE    := B//生成的静态库的名字LOCAL_STATIC_LIBRARIES := A//需要的静态库LOCAL_SRC_FILES := //需要的源文件 include $(BUILD_STATIC_LIBRARY)//生成静态库

Application.mk的内容和2中的一样。

4.用静态库libA.a和libB.a生成libC.so动态库

只需要Android.mk即可,内容如下:

LOCAL_PATH :=$(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE :=A BLOCAL_SRC_FILES :=libA.a libB.ainclude $(PREBUILT_STATIC_LIBRARY)include $(CLEAR_VARS)LOCAL_LDLIBS := -lm -llog//在c文件中打logLOCAL_MODULE :=C//生成的动态库的名字LOCAL_STATIC_LIBRARIES :=A B//依赖的静态库名字LOCAL_SRC_FILES:=//所需的源文件include $(BUILD_SHARED_LIBRARY)
5.生成的动态库在本项目中使用,或者在别的项目中调用。

src中的java文件如何调用:

/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.example.hellojni;import java.io.UnsupportedEncodingException;import java.nio.charset.Charset;import java.util.Hashtable;import org.apache.http.util.ByteArrayBuffer;import android.annotation.SuppressLint;import android.app.Activity;import android.widget.TextView;import android.os.Bundle;import android.os.Environment;//import com.android.ide.eclipse.ndk.*;public class HelloJni extends Activity{  public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);
<span style="white-space:pre"></span>}
    static {        System.loadLibrary("decode");//加载动态库,动态库要放在bin\ndk\local\armeabi目录下    }}

6.在windows命令行进入项目的bin\classes路径下,执行javah -d jni com.example.hellojni.HelloJni,前3个单词是包的名字,后一个单词是类名字。

会生成一个头文件,放在jni目录下

7.源文件的接口必须按照如下接口:

jbyteArray Java_com_example_hellojni_HelloJni_fun( JNIEnv* env,                                                  jobject thiz,jstring imagefile)

com_example_hellojni是包名

HelloJni是类名

fun是方法名

8.从java传入字符串给c

const char* jcstr = (const char *)(*env)->GetStringUTFChars(env,imagefile, 0 );//返回指向字符串的 UTF-8 字符数组的指针//LOGI("%s","MYLOG:BBB");int length=0;length= (*env)->GetStringUTFLength(env,imagefile)+1;//以字节为单位返回字符串的 UTF-8 长度LOGI("%d",length);char* rtn = (char*)malloc( length );memcpy(rtn,jcstr,length);//char* rtn = (char*)malloc( 33 );//memcpy(rtn,jcstr,33);char *aaa = rtn; (*env)->ReleaseStringUTFChars(env, imagefile, jcstr);//通知虚拟机平台相关代码无需再访问 utf

9.如果返回一个自己定义的中文字符串,那么在java中接受是没有问题的,但是我的项目提供的字符串是带中文的而且不知道是什么格式的,和自己定义的字符串不一样,所以最终决定返回byte数组,在java中转换为中文字符串 ,

unsigned char result[1000] = {0};memset(result,0,1000);//unsigned char test[] = "adfadf35345你说什么";len = strlen(result);LOGI("len::");LOGI("%d",len);jbyteArray data = (*env)->NewByteArray(env,len);// 我这里是byte型数组 1024是数组长度jbyte* pbuf = (jbyte*)malloc(len);memcpy(pbuf, result, len);(*env)->SetByteArrayRegion(env,data, 0, len, pbuf);LOGI("%s",data);free(pbuf);return data;

在java中

 String str2 = "";      try {str2 = new String(res,"GBK");} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();}

即可

ps:c和java的文件环境都是utf-8格式的


10.在c文件打log:

#include <android/log.h>

#define LOG_TAG "logfromc"#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

在Android.mk中加入一句:

include $(CLEAR_VARS)//此句下边LOCAL_LDLIBS := -lm -llog





0 0
原创粉丝点击