Android上如何用C语言编程--你好,世界!(2)

昨天Cygwin在线安装安到一半突然就停处了,这网太无耐了,今天只好去下了个离线安装包,http://download.csdn.net/

上面搜“cygwin 离线”,注意:下载下来的东西解压后的文件夹是ftp%...,包含%,&之类的特殊字符,把文件夹

名改成123什么的,不然会很莫名其妙的。害哥搞这个离线包搞了个把小时。

为了清楚,上个图:

 

 

敲个LS,什么东西都没有,这个目录是cygwin的安装目录下面的home文件夹下的用户名文件夹。

接下来是配置与Android相关的。在home/用户名,这个文件夹下有一个文件为.bash_profile,打开它,到最后添

加两行NDK的环境变量:

NDK_ROOT=/cygdrive/d/android-ndk-r6

export NDK_ROOT

上面的意思是,ndk的目录是,d:/android-ndk-r6

添加完之后,关闭Cygwin重新启动一下,然后敲入cd $NDK_ROOT,是否进入到ndk的目录了?否则就看看哪个字

母错了。

在ndk的目录下samples下有很多例子,随便弄个就可编译了。下面是新建一个项目,以对C语言在项目中的位置

更清楚。

打开Eclipse新建一个Android项目,取名hellojni,为了清晰,便于维护,及各种各样的好处,JNI的JAVA代码单独

一个类,单独一个包。其实最好能不用JNI就别用JNI,这东西负作用巨大,特别是在用到JNI复杂的地方,什么

内存啊,类型啊,哪里调用的方法,异常啊,可靠性都非常麻烦。非要用JNI的复杂功能,做好两件事,做之前充

分设计,设计之前充分学习一下JNI文档。当然对于一些简单的应用,那只需要充分仔细。作好参数,返回值的检

查,记得释放内存就行了。

新建了一个JNI的类JNIClass,里面申明一个将在C语言中实现的方法。如下:

package com.jjie.jni;

public class JNIClass {

 public native int GetSumFromCFunc(int a, int b);
}

C语言就是取两个数的和。

接下来在项目中新建一个文件夹jni,参考NDK目录下的sample中的hello-jni,把hello-jni中的jni目录下的

Android.mk拷贝到我们的项目中的jni文件夹,这个文件中的内容是告诉编译器要编译哪些文件,依赖哪些库,现

在里面很简单,照如下改动一下。

LOCAL_MODULE    := hellojni
LOCAL_SRC_FILES := hellojni.c

就是把那个'-'去掉了,山寨一下。hellojni.c是需要实现JAVA中方法的文件,但是怎么把JAVA中的函数名与C中的对

应起来就是下一步,C语言中的函数名不是随便取的,是通过java生成的。

在Windows的cmd中,进入项目的bin目录,用javah对JNIClass.class进行生成C语言方法的头文件,注意是.class文

件,不是.java文件。

javah -jni com.jjie.jni.JNIClass

成功后,在bin文件夹下生成了一个.h的头文件。把这个文件放到项目的jni这个目录中,在这个目录中再新建一个

hellojni.c的文件用来实现java的方法,c函数的原型已经在刚刚的头文件中了:

JNIEXPORT jint JNICALL Java_com_jjie_jni_JNIClass_GetSumFromCFunc
  (JNIEnv *, jobject, jint, jint);

我们只有两个整型的参数就是最后两个,至于前面两个是什么意思,阅读JNI文档。这个头文件中还引用到jni.h,

#include <jni.h>,注意把<>改成"",在ndk的目录中搜索一个jni.h,把搜到的这个文件同样放到jni的目录中。

hellojni.c实现函数:

#include "com_jjie_jni_JNIClass.h"

JNIEXPORT jint JNICALL Java_com_jjie_jni_JNIClass_GetSumFromCFunc
  (JNIEnv *env, jobject this, jint a, jint b)
{
 return a + b;
}

接下来是编译,用到Cygwin了,编译是用到NDK目录下的ndk-build,进入到我们项目的目录,如下命令编译:

$NDK_ROOT/ndk-build

结果:

conan@conan-PC /cygdrive/d/workspace36/hellojni
$ $NDK_ROOT/ndk-build
Compile thumb  : hellojni <= hellojni.c
SharedLibrary  : libhellojni.so
Install        : libhellojni.so => libs/armeabi/libhellojni.so

conan@conan-PC /cygdrive/d/workspace36/hellojni

在项目中刷新一下,发现多一个文件夹libs/armeabi/libhellojni.so。这个就是生成的库了,相当于Windows中的DLL

接下来就是去调用,在MainActivity中加载这个包,加载的时候注意去掉前缀lib。

在layout中的main.xml中的TextView加个id:   android:id="@+id/tvResult"

package com.jjie;

import com.jjie.jni.JNIClass;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends Activity {

 private TextView textView = null;
 
 //加载库
 static {
  System.loadLibrary("hellojni");
 }
 
 /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         setContentView(R.layout.main);


        JNIClass jniClass = new JNIClass();
        //调用JNI中的方法
        int result = jniClass.GetSumFromCFunc(1, 6);
       
        textView = (TextView)this.findViewById(R.id.tvResult);
        textView.setText(String.valueOf(result));
        
    }
}

运行吧。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值