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

本项目是生成静态库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中的A
LOCAL_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 B
LOCAL_SRC_FILES :=libA.a libB.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_LDLIBS := -lm -llog//在c文件中打log
LOCAL_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 block
		e.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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值