Android中使用jni调用第三方源码:grep(1)
来源:互联网 发布:linux 电源按钮 锁定 编辑:程序博客网 时间:2024/05/15 23:44
以前在Android中用jAVA实现了一个文件内容搜索的功能,对于大文件搜索简直是恶梦。抛开本身算法问题不谈,准备直接用jni调用linux中经常使用的grep,感谢开源软件带来的好处!
我需要的功能很简单,就是在一个文件中找到所有符合条件的字符串并打印它们的位置。这里使用了grep最初的版本grep 2.0,所有的源文件都在同一层目录。
1. 新建grep/jni目录,将所有*.c和*.h文件复制过去。
2. 修改grep.c文件,新建一个名为mysearch的函数,用于给jni层调用。
char* mysearch(argc, argv) int argc; char *argv[];{ char* search_result; char *keys; size_t keycc, oldcc, keyalloc; int keyfound, count_matches, no_filenames, list_files, suppress_errors; int opt, cc, desc, count, status; FILE *fp; extern char *optarg; extern int optind; int ii; resultFP = fopen(argv[4],"a"); fprintf(resultFP, "%i\n", argc); for(ii = 0; ii < argc; ii++) {fprintf(resultFP, "%s\n", argv[ii]); } prog = argv[0]; if (prog && strrchr(prog, '/')) prog = strrchr(prog, '/') + 1; keys = NULL; keycc = 0; keyfound = 0; count_matches = 0; no_filenames = 0; list_files = 0; suppress_errors = 0;// matcher = NULL; matcher = "fgrep";//固定搜索 while ((opt = getopt(argc, argv, "0123456789A:B:CEFGVX:bce:f:hiLlnqsvwxy")) != EOF) switch (opt) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':out_before = 10 * out_before + opt - '0';out_after = 10 * out_after + opt - '0';break; case 'A':out_after = atoi(optarg);if (out_after < 0) usage();break; case 'B':out_before = atoi(optarg);if (out_before < 0) usage();break; case 'C':out_before = out_after = 2;break; case 'E':if (matcher && strcmp(matcher, "egrep") != 0) fatal("you may specify only one of -E, -F, or -G", 0);matcher = "posix-egrep";break; case 'F':if (matcher && strcmp(matcher, "fgrep") != 0) fatal("you may specify only one of -E, -F, or -G", 0);;matcher = "fgrep";break; case 'G':if (matcher && strcmp(matcher, "grep") != 0) fatal("you may specify only one of -E, -F, or -G", 0);matcher = "grep";break; case 'V':fprintf(stderr, "%s\n", version);break; case 'X':if (matcher) fatal("matcher already specified", 0);matcher = optarg;break; case 'b':out_byte = 1;break; case 'c':out_quiet = 1;count_matches = 1;break; case 'e':cc = strlen(optarg);keys = xrealloc(keys, keycc + cc + 1);if (keyfound) keys[keycc++] = '\n';strcpy(&keys[keycc], optarg);keycc += cc;keyfound = 1;break; case 'f':fp = strcmp(optarg, "-") != 0 ? fopen(optarg, "r") : stdin;if (!fp) fatal(optarg, errno);for (keyalloc = 1; keyalloc <= keycc; keyalloc *= 2) ;keys = xrealloc(keys, keyalloc);oldcc = keycc;if (keyfound) keys[keycc++] = '\n';while (!feof(fp) && (cc = fread(keys + keycc, 1, keyalloc - keycc, fp)) > 0) { keycc += cc; if (keycc == keyalloc) keys = xrealloc(keys, keyalloc *= 2); }if (fp != stdin) fclose(fp);/* Nuke the final newline to avoid matching a null string. */if (keycc - oldcc > 0 && keys[keycc - 1] == '\n') --keycc;keyfound = 1;break; case 'h':no_filenames = 1;break; case 'i': case 'y':/* For old-timers . . . */match_icase = 1;break; case 'L':/* Like -l, except list files that don't contain matches. Inspired by the same option in Hume's gre. */out_quiet = 1;list_files = -1;break; case 'l':out_quiet = 1;list_files = 1;break; case 'n':out_line = 1;break; case 'q':out_quiet = 1;break; case 's':suppress_errors = 1;break; case 'v':out_invert = 1;break; case 'w':match_words = 1;break; case 'x':match_lines = 1;break; default:usage();break; } if (!keyfound) if (optind < argc) {keys = argv[optind++];keycc = strlen(keys); } else usage(); if (!matcher) matcher = prog; if (!setmatcher(matcher) && !setmatcher("default")) abort(); (*compile)(keys, keycc); if (argc - optind > 1 && !no_filenames) out_file = 1; status = 1; if (optind < argc)// while (optind < argc) {desc = strcmp(argv[optind], "-") ? open(argv[optind], O_RDONLY) : 0;if (desc < 0) { if (!suppress_errors) error(argv[optind], errno); }else { filename = desc == 0 ? "(standard input)" : argv[optind]; count = grep(desc); if (count_matches) {if (out_file) printf("%s:", filename);printf("%d\n", count); } if (count) {status = 0;if (list_files == 1) printf("%s\n", filename); } else if (list_files == -1) printf("%s\n", filename); }if (desc != 0) close(desc);optind=argc; } else { filename = "(standard input)"; count = grep(0); if (count_matches)printf("%d\n", count); if (count){ status = 0; if (list_files == 1) printf("(standard input)\n");} else if (list_files == -1)printf("(standard input)\n"); } fclose(resultFP);}
2. 新建grepJni.c文件,用于调用grep.c中的mysearch方法,并给Java层提供名为grep的方法。内容如下:
#include <string.h>#include <jni.h>#include <dlfcn.h>#include <android/log.h>#include <stdlib.h>#define LOG_TAG "grepJni"#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)JNIEXPORT void JNICALL Java_com_lsj_TextSearch_grep(JNIEnv *env, jobject obj, jstring jtext, jstring jpath, jstring jlogpath){LOGI("open so success!");char* text = (*env)->GetStringUTFChars(env, jtext, NULL);char* path = (*env)->GetStringUTFChars(env, jpath, NULL);char* logpath = (*env)->GetStringUTFChars(env, jlogpath, NULL);char* sa[] = {"grep", "-b", text, path, logpath};mysearch(5,sa);}3. 新建Android.mk文件:
#获取当前目录LOCAL_PATH := $(call my-dir)#清除一些变量include $(CLEAR_VARS)#要生成的库名LOCAL_MODULE := grep#库对应的源文件LOCAL_SRC_FILES := alloca.c dfa.c grep.c obstack.c search.c getopt.c kwset.c regex.c grepJni.c#libtest.so需要引用的库libdl.so:加载动态函数需要,liblog.so 日志打印需要,默认是system/lib目录下LOCAL_LDLIBS := -ldl -llog #生成动态库libgrep.soinclude $(BUILD_SHARED_LIBRARY)4. 编译生成so文件。
下载Android NDK,并将NDK加入环境变量。
在前面的grep目录下运行ndk-build,生成libgrep.so文件。将该文件复制到Android项目的libs/armeabi目录下。
4. 在Java中调用grep.so。
在com.lsj.TextSearch类(该类名必须与第2步中的com_lsj_TextSearch名称匹配)中,调用grep库。
载入动态库:
static {System.loadLibrary("grep");}其中System.loadLibrary中的grep对应/libs/armeabi中的libgrep.so,Android后自动过滤前面的lib和后面的.so。
声明grep函数:
public native void grep(String text, String path, String logPath);调用grep函数:
grep(searchText, filePath, logPath);
该函数作用是在filePath中搜索searchText字符串,并将搜索结果存放在logPath文件中。
0 0
- Android中使用jni调用第三方源码:grep(1)
- android JNI 调用第三方动态库
- Android-jni 调用第三方动态库
- Android.mk JNI 调用第三方库
- 使用JNI调用第三方.so文件
- Android Studio中使用JNI和第三方.so库
- jni 调用第三方dll
- android JNI 使用的两种形式 --自己实现c和调用第三方so库
- android JNI学习之二 调用第三方动态库
- android jni开发 调用 第三方 动态链接库
- Android平台下JNI调用第三方so库
- Android studio jni内调用第三方so
- Android平台下JNI调用第三方so库
- Android平台下JNI调用第三方so库
- Android平台下JNI调用第三方so库
- Android studio jni内调用第三方so
- Android studio Jni调用第三方库(CMakelist)
- JNI中调用第三方提供的so文件
- MFC中获取App,MainFrame,Doc和View类等指针的方法
- Linux块设备驱动的模块加载与卸载
- 17-1-(2)用引用排序
- 双数组AC自动机
- 介绍两种在c++中调用dll的方法
- Android中使用jni调用第三方源码:grep(1)
- Windows与Linux之间拷贝数据的方法
- Twitter Storm简介与入门
- 查找算法的实现和比较
- MFC中文件读写的几种方法
- iOS 企业证书发布app 流程
- salesforce 错误提示窗口
- archive log
- xmpp1