android SDK使用cygwin编译.so文件
2014-04-27 02:36
405 查看
最近要使用JNI调用一个C库,所以就趁这个时候学习一下JNI在android中怎样使用。
2、测试cygwin,输入make -v,gcc -v,看是否正常运行。
3、配置cygwin。找到cygwin的安装路径下的 .bash_profile文件,我的路径是:C:\cygwin64\home\ASUS,使用记事本打开这个文件,然后
在文件的末尾加上这两段代码:(注意其中ANDK这个名字可以自己随便取,但是两行代码的ANDK必须相同)
ANDK=/cygdrive/e/doMyself/android-ndk-r6b-windows/android-ndk-r6b
export ANDK
这样cygwin便配置完成了,这一步的主要问题是cygwin实在是太难下载了,其他的都很简单。
其实只要编写好native方法就行,其他的逻辑可以以后再加上。
2、使用javah工具将native方法编译生成.h头文件,步骤如下:
一、使用cmd进入到你所在的android项目bin目录下的classes文件夹下,然后执行命令:javah -jni [包名].[native方法所在的类名],如我根据我的包名
使用的就是这样的命令:javah -jni com.lonuery.jni.JNIMethod。生成了文件:com_lonuery_jni_JNIMethod.h,打开这个文件可以看见其代码如下:
3、根据头文件编写.cpp文件,其实也可以先编写.cpp文件,然后根据头文件将.cpp文件的函数名称改变即可。我就是想编写好了.cpp文件,然后
对其进行的修改而已。编写好的.cpp文件代码如下:
这里要注意几点:
1.在头文件中只有参数类型而无参数,所以要自己手动加上参数名,如:x,n等等。
2.你会发现我的native方法只有两个参数,但是.h头文件却有4个参数了,这里前面两个参数是无用的(到底有什么作用以及怎么生成的我也不知道),
你只需要关心你native方法中定义的两个参数即可。所以在写.cpp文件时有一个简单的办法就是:将.h头文件的函数名称复制过来,然后手动加上
形参名称即可。
3.如果你使用的是C++语言写的,在.cpp文件中要使用extern "C"{.....}将C++代码括起来,具体如上面的代码所示。这样做是因为在所生成的二进制
文件中,c和C++的符号不同所造成的,JNI是按照c的规则去找函数,所以要加上extern c,让编译器按照C的规则去编译函数,这样JNI才能够被调
用。
4、在android工程项目的根目录下新建一个jni文件,将.h以及.cpp文件导入到这个文件夹下。
5、编写Android.mk文件内容如下:
第一行代码:定位源文件的位置,必须处于最开始,他的作用是返回当前目录的路径。
第二行代码:清除一些变量的值,但是LOCAL_PATH除外。
第三行代码:用来指定当前待编译模块的名称,如这次我要编译的模块为即为我所创建的工程MyJNIProject
第四行代码:用来指定参与编译的源代码文件,这里我要编译即为之前编写的JniProject.cpp文件。
第五行代码:用来指示将当前模块编译为共享库,前缀为lib,后缀为.so。
6、编写Application.mk文件,其作用是描述在你应用中所需要的模块(动态库或者静态库),内容如下:
具体的编写规则以及每行代码的含义,请看下面这篇博客:Application.mk语法点点
7、将编写好的Android.mk以及Application.mk文件放入之前所创建的jni文件夹中。
8、使用cygwin编译生成.so文件:
一、进入你所创建项目的根目录:cd /cygdrive/e/MyEclipse/MyJNIProject,记住:在cd命令前必须要加上cygdrive才能够进入,上面的命令必须一次性
输入。
二、输入命令:ANDK/ndk-build,这个ANDK就是之前.bash_profile配置文件中所设置的名称。
效果图如下:
编译好了之后,将会在项目的根目录下多出一个obj文件夹,在lib文件夹下会多出一个armeabi文件夹。
好了现在对native方法进行调用:
效果如下:
至此android NDK调用C++源文件就介绍完成了。
一配置环境:
1、下载安装cygwin(cygwin的下载文件太大了将近6G,安装后的安装文件达到了将近20G),具体的下载安装步骤我记不贴出来了,比较简单。2、测试cygwin,输入make -v,gcc -v,看是否正常运行。
3、配置cygwin。找到cygwin的安装路径下的 .bash_profile文件,我的路径是:C:\cygwin64\home\ASUS,使用记事本打开这个文件,然后
在文件的末尾加上这两段代码:(注意其中ANDK这个名字可以自己随便取,但是两行代码的ANDK必须相同)
ANDK=/cygdrive/e/doMyself/android-ndk-r6b-windows/android-ndk-r6b
export ANDK
这样cygwin便配置完成了,这一步的主要问题是cygwin实在是太难下载了,其他的都很简单。
二编写android工程以及C++代码
1、新建一个android工程,编写好native方法:public class JNIMethod { public JNIMethod(){ load(); } private void load() { try { System.loadLibrary("MyJNIProject"); } catch (Throwable e) { e.printStackTrace(); } } private static JNIMethod jniMethod; public static JNIMethod Instance() { if(jniMethod == null) jniMethod = new JNIMethod(); return jniMethod; } public native double power(double x,int n); public native int calculate(int x, int y); }
其实只要编写好native方法就行,其他的逻辑可以以后再加上。
2、使用javah工具将native方法编译生成.h头文件,步骤如下:
一、使用cmd进入到你所在的android项目bin目录下的classes文件夹下,然后执行命令:javah -jni [包名].[native方法所在的类名],如我根据我的包名
使用的就是这样的命令:javah -jni com.lonuery.jni.JNIMethod。生成了文件:com_lonuery_jni_JNIMethod.h,打开这个文件可以看见其代码如下:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_lonuery_jni_JNIMethod */ #ifndef _Included_com_lonuery_jni_JNIMethod #define _Included_com_lonuery_jni_JNIMethod #ifdef __cplusplus extern "C" { #endif /* * Class: com_lonuery_jni_JNIMethod * Method: power * Signature: (DI)D */ JNIEXPORT jdouble JNICALL Java_com_lonuery_jni_JNIMethod_power (JNIEnv *, jobject, jdouble, jint); /* * Class: com_lonuery_jni_JNIMethod * Method: calculate * Signature: (II)I */ JNIEXPORT jint JNICALL Java_com_lonuery_jni_JNIMethod_calculate (JNIEnv *, jobject, jint, jint); #ifdef __cplusplus } #endif #endif
3、根据头文件编写.cpp文件,其实也可以先编写.cpp文件,然后根据头文件将.cpp文件的函数名称改变即可。我就是想编写好了.cpp文件,然后
对其进行的修改而已。编写好的.cpp文件代码如下:
#include <jni.h> #include <stdio.h> #include <stdlib.h> #include "com_lonuery_jni_JNIMethod.h" extern "C" { JNIEXPORT jdouble Java_com_lonuery_jni_JNIMethod_power(JNIEnv *env ,jobject thiz ,jdouble x ,jint n) { double val = 1.0; while(n--){ val*=x; } return val; } JNIEXPORT jint Java_com_lonuery_jni_JNIMethod_calculate(JNIEnv *env ,jobject thiz ,jint x,jint y) { if(x>y) { return x; }else{ int result = x + y ; return result; } } }
这里要注意几点:
1.在头文件中只有参数类型而无参数,所以要自己手动加上参数名,如:x,n等等。
2.你会发现我的native方法只有两个参数,但是.h头文件却有4个参数了,这里前面两个参数是无用的(到底有什么作用以及怎么生成的我也不知道),
你只需要关心你native方法中定义的两个参数即可。所以在写.cpp文件时有一个简单的办法就是:将.h头文件的函数名称复制过来,然后手动加上
形参名称即可。
3.如果你使用的是C++语言写的,在.cpp文件中要使用extern "C"{.....}将C++代码括起来,具体如上面的代码所示。这样做是因为在所生成的二进制
文件中,c和C++的符号不同所造成的,JNI是按照c的规则去找函数,所以要加上extern c,让编译器按照C的规则去编译函数,这样JNI才能够被调
用。
4、在android工程项目的根目录下新建一个jni文件,将.h以及.cpp文件导入到这个文件夹下。
5、编写Android.mk文件内容如下:
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := MyJNIProject LOCAL_SRC_FILES := JniProject.cpp include $(BUILD_SHARED_LIBRARY)
第一行代码:定位源文件的位置,必须处于最开始,他的作用是返回当前目录的路径。
第二行代码:清除一些变量的值,但是LOCAL_PATH除外。
第三行代码:用来指定当前待编译模块的名称,如这次我要编译的模块为即为我所创建的工程MyJNIProject
第四行代码:用来指定参与编译的源代码文件,这里我要编译即为之前编写的JniProject.cpp文件。
第五行代码:用来指示将当前模块编译为共享库,前缀为lib,后缀为.so。
6、编写Application.mk文件,其作用是描述在你应用中所需要的模块(动态库或者静态库),内容如下:
APP_PROJECT_PATH := $(call my-dir)/.. APP_MODULE := MyJNIProject APP_ABI := armeabi
具体的编写规则以及每行代码的含义,请看下面这篇博客:Application.mk语法点点
7、将编写好的Android.mk以及Application.mk文件放入之前所创建的jni文件夹中。
8、使用cygwin编译生成.so文件:
一、进入你所创建项目的根目录:cd /cygdrive/e/MyEclipse/MyJNIProject,记住:在cd命令前必须要加上cygdrive才能够进入,上面的命令必须一次性
输入。
二、输入命令:ANDK/ndk-build,这个ANDK就是之前.bash_profile配置文件中所设置的名称。
效果图如下:
编译好了之后,将会在项目的根目录下多出一个obj文件夹,在lib文件夹下会多出一个armeabi文件夹。
好了现在对native方法进行调用:
public class MainActivity extends Activity implements OnClickListener{ TextView tv; Button btn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv = (TextView)findViewById(R.id.tv); btn = (Button)findViewById(R.id.btn); btn.setOnClickListener(this); } @Override public void onClick(View arg0) { int result = JNIMethod.Instance().calculate(5, 2); double power = JNIMethod.Instance().power(6, 3); tv.setText("result:"+result+" power:"+power); } }
效果如下:
至此android NDK调用C++源文件就介绍完成了。
相关文章推荐
- cygwin+android ndk编译供给Android使用的.so库文件
- 不使用Cygwin,在eclipse中快速开发JNI,一键生成C头文件.h,以及一键使用NDK交叉编译
- 不使用Cygwin,在eclipse中快速开发JNI,一键生成C头文件.h,以及一键使用NDK交叉编译
- 不使用Cygwin,在eclipse中快速开发JNI,一键生成C头文件.h,以及一键使用NDK交叉编译
- 使用Eclipse+NDK编译arm64-v8a CPU架构的speex.so文件
- android studio 使用ndk编译.C文件生成so文件
- python文件编译成so介绍 - 2.使用makefile将py文件编译成so文件并制作成rpm包,实现自动化
- Android NDK学习(4)使用cygwin生成.so库文件
- GCC 编译动态库 so文件时,静态链接libmysqlclient.a 与动态链接参数一起使用问题。
- AndroidStudio 2.2.3:编译C++文件、生成so文件及so文件使用
- 不使用Cygwin,在eclipse中快速开发JNI,一键生成C头文件.h,以及一键使用NDK交叉编译
- 使用NDK编译C/C++为.so文件
- 使用cython将py文件编译成so文件
- 不使用Cygwin,在eclipse中快速开发JNI,一键生成C头文件.h,以及一键使用NDK交叉编译
- SO文件的编写,编译,使用方法
- cygwin+windows 使用JNI时 .c文件打包成.so
- android NDK开发使用Builder自动编译生成so文件
- Android NDK学习(4)使用cygwin生成.so库文件
- python文件编译成so介绍 - 1.使用cython将py文件编译成so文件