利用Ubuntu将c++文件生成.so库

前端之家收集整理的这篇文章主要介绍了利用Ubuntu将c++文件生成.so库前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

记录生成.so库的步骤,以防自己每次忘记。用的是eclipse。

一、先在eclipse中生成一个android工程,然后在android工程下的src新建一个package,例如名字为com.android.aa,在其下新建一个java文件,这个文件相当于与.so库的一个对接接口,其形式为:

package com.android.aa;

public class NativeAA{

static{

System.loadLibrary("aa"); //加载aa.so库

}

public native byte[] sent(String input); //调用so库中的sent函数

}

保存一下,就可以在./bin/classes/com/android/aa文件生成NativeAA.class文件


二、利用javah生成jni的头文件

首先利用cmd进入目录中:例如工程放在了F盘,工程为test:

f: //这是进入了f盘

cd ./test/bin/classes目录下,运行下一命令:

javah com.android.aa.NativeAA

就会在classes生成了一个com_android_aa_NativeAA.h的头文件

里面就是一个函数的声明:

JNIEXPORT jbyteArray JNICALL Java_com_android_aa_NativeAA_sent

(JNIEnv*,jobject,jstring);(其他的省略,并且java中有几个函数声明,.h就对应生成几个,我这里是一个)

三、生成与.h对应的.cpp文件

在Ubuntu中建立一个文件夹,例如:我在project的文件下建立了一个aa的文件下,然后建立一个jni文件下,将com_android_aa_NativeAA.h方进去,再新建一个对应的.cpp

,在命令窗口输入geditcom_android_aa_NativeAA.cpp,就建立以个.cpp文件。再建立实现sent函数的.cpp和.h这里命名为sent.cpp和sent.h。

sent.cpp的中的函数sent实现的是输入为char*,输出的参数为char*类型,其声明为:

int sent(char* sentInput,char **sentInput);

char*sentInput是输入,char**sentInput是输出(实际需要的是char*,返回二级指针下面会说明),返回int是标志位,这个程序运行下来返回0表示成功;其他值表示失败。

com_android_aa_NativeAA.cpp的形式:

#include "com_android_aa_NativeAA.h"

#define TAG "so-jni"

#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__) //

//功能:实现将jstring转换为char*

char*jstringTostring(JNIEnv*env,jstring jstr);

JNIEXPORT jbyteArray JNICALL Java_com_android_aa_NativeAA_sent

(JNIEnv*env,jobject object,jstring jinput) //jstring jinput对应的是java文件中的String input

{

//首先将jstring转成char类型,因为我的例程中sent.cpp中的函数的输入参数是char*;

char *inputChar=jstringTostring(env,jinput);

if(inputChar==NULL)

{

LOGD("jstring转换char失败!")

return NULL;

}

else

{

char *outData=new char[255];

memset(outData,255);

if(outData==NULL)

return NULL;

int ret=sentInput(InputChar,&outData); //outData是返回值,&outData这样做是返回一组数组。

if(ret==0)

{

//这是将c++中的char*转为为java中的byte[];

jbyte *joutData=(jbyte*)outData;

jbyteArray jarrOutData=env->NewByteArray(255);

env->SetByteArrayRegion(jarrOutData,255,joutData);

delete[ ] outData;

return jarrOutData;

}

else

{

delete[] outData;

return NULL;

}

}

delete[ ] inputData;

}

//将Java中的String转换为c++中的char*

char*jstringTostring(JNIEnv* env,jstring jstr)

{

char*ttn=NULL;

jclass clsstring=env->env->FindClass("java/lang/string");

jstring strInput=env->NewStringUTF("utf-8");

jmethodID mid=env->GetMethodID(clsstring,"getBytes","(Ljava/lang/String;)[B");

jbyteArray barr=(jbyteArray)env->CallObjectMethod(jstr,mid,strencode);

jsize alen=env->GetArrayLength(barr);

jbyte*ba=env->GetByteArrayElements(barr,JNI_FALSE);

if(alen>0)

{

rtn=(char*)malloc(alen+1);

memcpy(rtn,ba,alen);

rtn[alen]=0;

}

env->ReleaseByteArrayElements(barr,0);

return rtn;

}

四、两个makefile文件

(1)Application.mk:用于描述APP需要的native model

内容为:

APP_PLATFORM :=android-19

APP_STL :=gnustl_static #要使用到的标准c++库

APP_CPPFLAGS :=-frtti -fexceptions

APP_ABI :=armeabin

分析:

Application.mk常用的有四个:

a. APP_PLATFORM :=android-19

表示使用ndk库函数版本号。一般和SDK的版本相对应,各个版本在NDK目录下的platforms文件夹中

b. APP_STL :=stlport_static

定义NDK的编译系统的运行时库,有如下几种:

system:默认最小的c++运行库,生成的应用体积小,内存占用少,但部分功能将无法支持

stIport_static:使用STLport作为静态库(推荐使用)

stlport_shared:STLport作为动态库(不推荐,可能产生兼容性和部分低版本的Android固件)

gnustl_static:使用GNU libstdc++作为静态库

c. APP_ABI:=armeabi

表示要编译成对应指令集cpu的动态库,armeabi:ARMv7指令集,armeabi-v7a:ARMv7+硬件FPU指令集,x86:IA-32指令集,all支持常用的指令集

d. APP_CPPFLAGS:该变量列出了一些编译器标志,在便以任何模块的c++代码时这些标志都会被传给编译器;

e. APP_OPTIM:=debug(我自己的项目没用这一项)

设置编译类型,debug:调试版本,so动态库中带调试信息(可以使用gdb-server尽心动态段断点低调试),release:发布版本,so库不带调试信息

(2)Android.mk:用于描述构建系统的源文件以及shareed libraries。

内容

LOCAL_PATH :=&(call my-dir)

APP_STL :=gnustl_static #要用到标准c++库,如果不用可以注释掉

include $(CLEAR_VARS)

LOCAL_LDLIBS:=-llog

LOCAL_MODULE :=aa #aa为行程so库的库名

LOCAL_SRC_FILES :=sent.cpp \

com_android_usbkey_NativeUsbBase.cpp \

LOCAL_CFLAGS :=-arm -mfloat-abi=softfp -mfpu=vfp -Wmultichar

include $(BUILD_SHARED_LIBRARY)

总结:

要行程.so库的流程就这些(可根据自己的情况添加.cpp),需注意的是:ubuntu上必须安装ndk上述文件才可以形成.so库。

在命令窗口需输入的:

1.首先进入jni文件所在的目录(删除文件都放在jni文件里);

2.输入命令:ndk-build即可生成so库(注意:清楚so库的命令为:ndk-build clean)

原文链接:https://www.f2er.com/ubuntu/352485.html

猜你在找的Ubuntu相关文章