注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

Android系列三简单动态库的调用  

2013-03-26 18:59:33|  分类: Android |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Android系列三简单动态库的调用

前面的环境搭建好了,那么下来就是要干活了,先来一个比较简单的,打开ECLIPSE,建立一个安卓的应用工程。

然后在界面了拖出一个BUTTON,在XMl文件中,编辑android:OnClick=”MyTestClick”,然后在类中书写这个函数。这样就可以避免写监听器了,毕竟对这个还不是太熟,怎么简单怎么来,这个看上去和SL中的有些类似,不知道谁抄谁啊。

定义一个本地的函数,告诉编译器要使用so或者a的库文件。

Public native int TestSo(int iTemp);

然后声明调用的库:

Static{

 System.LoadLibrary(“mytestso”);

}

这里说明一下,函数的声明使用native这个关键字,说明这个函数是调用的本地的库文件导出的函数。后面的static部分,静态加载mytestso这个库。而这个库的名字你可以在android.mk文件定义。

下来这步最重要,在工程新建一个jni文件夹。记住,一定要建立这个文件夹,没有这个,可能会出一些意想不到的错误。

然后使用:

  Javah –classpath bin\classes –d jni com.example.mytestso.MyTestSo

说明一下,-classpath指你的java文件生成的class文件的位置,记住,一定要生成这个类文件才可以使用这个命令。JNI指你的刚刚生创建的jni文件夹,后面是你要编译的class的具体的名称,包括名空间,这样,就不用在前的path中,一级级的指定路径了。

如果没有错误的话,会在JNI文件夹中生成一个com_example_mytestso_MyTestSo.h文件。

打开这个文件,将其中的函数声明拷贝,然后在JNI中再创建一个c文件,MyTestSo.c,然后把刚刚拷贝的声明复制到其中,进行修改。

注意,声明的时候儿是没有具体的参数的,而且记得要去掉函数后面的分号。否则会报:

error: parameter name omitted XXx前面需要定义之类的错误。

如果是为了兼容C++C文件,要在开始:

#ifdef __cplusplus
extern "C" {
#endif

#include "myc.h"

#ifdef __cplusplus
}
#endif

都是些常用的用法,就不细讲了。

JNIEXPORT jint JNICALL Java_com_example_mytestso_IrisLib_TestSo (JNIEnv *env, jobject thiz)
{
int iRet = 0;

return iRet;
}

其中JNIEXPORT JNICALL两个参数可以不写,但写上挺好。Int对应 jint,这个具体的用法大家得看一下相关的文档,网上很多。

这时候儿,还有一个相当重要的文件需要手动建立,那就则前面提到的android.mk,在JNI路径下与C文件一起。

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := mytestso.c

LOCAL_MODULE := IrisLib
include $(BUILD_SHARED_LIBRARY)

这里遇到了一个错,make: * No rule to make target '/native.c', needed by '/Users/ivan/Documents/workspace/TestNDK/obj/local/armeabi/objs/myNDK/native.o'. Stop.

原因是第一行多写了一个“-”字符。因为上文中选择了自动编译,所以成功后会在工程中自动创建一个libs\armeabi\libmytestso.so,实际上调用,libmytestso.so前面的lib可以去掉。

一开始运行,遇到了“unfortunately activity has stopped”这个错误,SO根本调不出来,直接就崩溃。后来想了几个办法也没有解决。只好重新建立了一个新的工程,然后就好了,估计是名字的问题。

这样,在JAVA文件中可以调用这个函数,然后用对话框弹出来:

new AlertDialog.Builder(MyTestSo.this)
     .setTitle(Integer.toString(t))
     .setMessage(Integer.toString(TestSo(36)))
     .create()
     .show();

结果就顺利的出来了。

但是这样的话,如果数据很多怎么办,如何调试?如何传递数组?对象?指针。别急下来会一点点的整理出来。

筚路蓝缕,以启山林之秀。

  评论这张
 
阅读(594)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017