Jni开发编译中的几个错误

1、背景介绍

最近有个项目,需要客户端发送短信,但是被360提示报毒了,还有一个问题就是不太安全,怎么办呢?这个时候,我们的处理方式是使用了JNI调用Java方法,来发送短信。但是在编译的过程中,出现了几个问题,这里来简单总结一下。

2、问题一

2.1 出错信息

这里直接贴出错误代码,以搜索引擎的强大,会很快就搜出来。

Android NDK: WARNING: APP_PLATFORM android-17 is larger than android:minSdkVersion 11 in ./AndroidManifest.xml
[armeabi-v7a] Compile thumb  : sendmsg <= sendmsg.c
jni/sendmsg.c: In function 'Java_com_hello_jni_utils_JniUtils_sendSms':
jni/sendmsg.c:14:23: error: request for member 'FindClass' in something not a structure or union
jni/sendmsg.c:16:22: error: request for member 'GetStaticMethodID' in something not a structure or union
jni/sendmsg.c:18:20: error: request for member 'NewObject' in something not a structure or union
jni/sendmsg.c:21:8: error: request for member 'GetMethodID' in something not a structure or union
jni/sendmsg.c:25:7: error: request for member 'CallVoidMethod' in something not a structure or union
make.exe: *** [obj/local/armeabi-v7a/objs/sendmsg/sendmsg.o] Error 1

2.2 问题解析

这个错误当中,主要的问题是,找不到这个方法。但是我明明在系统中定义了该方法呀,哪里出错了呢?

我仔细检查了代码,发现代码并没有调用额外的方法,我在文件的头部也包含了相关头文件,如:

#include <jni.h>
#include <string.h>
#include <stdio.h>

后来发现一个问题,我是将这个文件用C++编译过的,没有问题。移植的时候,将系统使用了C文件命名,就出错了,那我再改回去行不行?好吧,测试通过,可行。

2.3 原因解析

深入分析之后,发现了是C语言语法格式与C++的差异导致的,如果是c程序,要用 (*env)->,如果是C++要用 env->。我在代码中,主要有这样的一个方法调用:

jobject sms = env->NewObject( smsclazz, get);
jclass smsclazz = env->FindClass("android/telephony/SmsManager");

在linux下如果.c文件中用 “env->” 编译会找不到此结构,必须用“(*env)->”,或者改成.cpp文件,以 c++的方式来编译。

3、问题二

3.1 问题描述

在修改了2中的错误,再次编译的时候,发现一个问题,就是当我的文件修改成为了cpp文件之后,提示说c文件找不到,主要报错信息如下:

make.exe: *** No rule to make target `jni/sendmsg.c', needed by `obj/local/armeabi-v7a/objs/sendmsg/sendmsg.o'.  Stop.

我挺纳闷的,我已经将c文件修改为cpp文件了呀,就算要提示,也应该提示cpp文件找不到才对呀。

3.2 解决方案猜测

好吧,是不是我的配置文件不对呢,我去检查了一下,我已经将文件修改为了cpp命名文件,如下:

LOCAL_SRC_FILES := sendmsg.cpp

我再仔细看看错误信息,说的是在make过程中,没有找到sendmsg.o文件。额,难道有缓存???将程序clean一下,出现一样的错误,暂时不去管他,看到目录下多出一个文件夹obj,如下:

3.3 解决方案

删掉obj文件,重新clean一下,OK!

4、问题三

4.1 问题描述

问题解决的差不多了,可是坑爹的又出现了一个问题,是什么呢?说是在链接的时候找不到这个方法,额,啥意思呀,我直接贴错误信息好了:

11-04 14:27:52.750: E/AndroidRuntime(27773): FATAL EXCEPTION: main
11-04 14:27:52.750: E/AndroidRuntime(27773): java.lang.UnsatisfiedLinkError: Native method not found: 

com.common.library.utils.JniUtils.sendSms:(Ljava/lang/String;Ljava/lang/String;)V
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at com.common.library.utils.JniUtils.sendSms(Native Method)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at com.paying.player.sms.SmsSendManager.sendSms(SmsSendManager.java:82)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at com.paying.player.sms.SmsSendManager.sendSms(SmsSendManager.java:115)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at com.paying.player.SplashActivity.sendSms(SplashActivity.java:98)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at com.paying.player.SplashActivity.onCreate(SplashActivity.java:47)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at android.app.Activity.performCreate(Activity.java:5184)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at com.qihoo360.mobilesafe.loader.b.callActivityOnCreate(SourceFile:81)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2078)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2139)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at android.app.ActivityThread.access$700(ActivityThread.java:143)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1241)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at android.os.Handler.dispatchMessage(Handler.java:99)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at android.os.Looper.loop(Looper.java:137)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at android.app.ActivityThread.main(ActivityThread.java:4963)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at java.lang.reflect.Method.invokeNative(Native Method)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at java.lang.reflect.Method.invoke(Method.java:511)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1038)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:805)
11-04 14:27:52.750: E/AndroidRuntime(27773): 	at dalvik.system.NativeStart.main(Native Method)

4.2 解决方案

其实出现这个问题挺坑爹的,首先,我看了下,是否已经使用了static静态代码块,将编译之后的so文件包含进来?代码如下:

static {
		System.loadLibrary("sendmsg");
	}

已经包含了呀,没问题。

那么,是不是参数列表不对呢?我仔细检查了一下,参数列表也没有问题。

再看,是不是参数的返回值有问题,导致程序除了问题呢?仔细看看,也没有问题(java代码和c++代码都没问题)。

坑爹了,到底什么地方出问题了,之前不是挺靠谱的么?我后来想起来,之前的时候用过一个头文件信息的,里面有一个继承c的语句,难道是这个问题?添加代码如下:

ok,编译成功。

4.3 成功信息

编译成功之后的信息,应该如下所示:

时间: 2024-09-08 23:43:09

Jni开发编译中的几个错误的相关文章

VS2015+OpenGL4.0开发编译时弹出错误:glaux.lib(tk.obj) : error LNK2019: 无法解析的外部符号 _sscanf,该符号在函数 [email&#160;protected] 中被引用

一.问题描述: VS2015+OpenGL4.0开发编译时弹出如下所示的错误: 1>glaux.lib(tk.obj) : error LNK2019: 无法解析的外部符号 _sscanf,该符号在函数 [email protected] 中被引用 1>glaux.lib(tk.obj) : error LNK2019: 无法解析的外部符号 _vsprintf,该符号在函数 _PrintMessage 中被引用 二.问题原因: VS2015默认编译时将许多标准库采用内联方式处理,因而没有可以链

Android jni开发有哪些常见的错误

我们在Android jni开发中,特别是对于刚入门学习Android jni开发的同学来说,往往会遇到很多错误,这里总结了我们经常遇见的错误.这些错误,你是否经常遇到. 错误1:java.lang.UnsatisfiedLinkError: Native method not found: 本地方法没有找到 1.本地函数名写错 2.忘记加载.so文件 没有调用System.loadlibrary 错误2:findLibrary returned null 1.System.loadLibrar

android NDK开发编译C++文件出现Type &#39;jint&#39; could not be resolved和Unresolved inclusion: &lt;jni.h&gt;的解决办法

今天在编译android NDK工程的时候,在jni文件夹下的cpp文件中报了一大堆错误,诸如:Unresolved inclusion: <jni.h>.Type 'jint' could not be resolved.Type 'jintArray' could not be resolved等,根据经验,这样的错误肯定是没有包含相应的头文件导致的. 解决方案: 选中工程,右键->Properties,点击C/C++ General展开,点击Path and Symbols,在右边

让你提前认识软件开发(51):VC++集成开发环境中Linux下Pclint工程的配置方法及常见错误修改

第3部分 软件研发工作总结 VC++集成开发环境中Linux下Pclint工程的配置方法及常见错误修改 [文章摘要] Pclint是一种C/C++软件代码静态分析工具.它是一种更加严格的编译器,能够发现普通编译器所不能发现的代码中的很多问题,因此被广泛应用于软件开发项目中. 本文介绍了如何在VC++集成开发环境中配置Linux下的Pclint工程,给出了C语言中pclint规则A检查的常见错误,并描述了对应的修改办法. [关键词] VC++  Pclint  配置  操作  修改 1. 前言 P

Wabpack系列:在webpack+vue开发环境中使用echarts导致编译文件过大怎么办?

现象,在一个webpack+vue的开发环境中,npm install echarts --save了echarts,然后在vue文件中直接使用 import echarts from 'echarts' 然后编译的时候加上了Uglify选项,发现vendor文件的大小已经达到了800多k,导致首次加载速度比较慢,然后我们这个是webapp,就更慢了. 所以考虑把echarts提取出来,改用cdn版本的echarts,具体操作步骤如下: (0)找到可用的echartscdn资源 在bootcdn

cocos2d-x3.2中将XCode开发的工程转移至VS2010中可能会出现的错误

网上有些代码是xcode写的,我们想在我们自己屌丝的vs上面运行,那要重新建工程,然后载入.但是万万 没想到在VS里新建工程再添加文件,编译后出现了好多错误.下面就把解决这些错误的方法写下来,与大家分享. 1. 首先要把文件格式用文本文件另存为Unicode格式,不然VS会报一些莫名其妙的错误. 2. VS里不能用bzero函数,改为memset. XCode: //bzero(fileName, MAX_FILENAME_LENGTH); 改为: VS: memset(fileName, 0,

55 gcc编译中出现“游离”错误

exam1204button.c:26:3: 错误: 程序中有游离的'\200' exam1204button.c:26:3: 错误: 程序中有游离的'\235' exam1204button.c:26:3: 错误: 程序中有游离的'\342' exam1204button.c:26:3: 错误: 程序中有游离的'\200' exam1204button.c:26:3: 错误: 程序中有游离的'\235' 类似的错误大多数都是由于中文输入法输入的字符和英文字符不同导致的,检查引号.括号.分号 5

linux 编译中required file `./ltmain.sh&#39; not found 错误的解决办法(转)

在linux下编译c/c++程序出错:$ automake --add-missing....configure.in:18: required file `build/ltmain.sh' not found .... -------------------------------------------------------- 解决方案(libtoolize配置即可): $libtoolize --version-libtoolize (GNU libtool) 1.4.2.....$li

当用Myeclipse8.6集成开发环境,进行JavaWeb项目开发的时候,用集成开发环境中的run Server进行程序调试时,出现如下错误解决方案

当用Myeclipse8.6集成开发环境,进行JavaWeb项目开发的时候,用集成开发环境中的run Server进行程序调试时,出现如下错误解决方案: 'Starting Tomcat v6.0 Server at localhost'has encountered a problem 错误提示: Several ports(8080,8009)required by Tomcatv6.0 Server at localhost are already in use.The server ma