java jni 调用 c 代码, c 中 unsigned char* 数据 如何传给java?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java jni 调用 c 代码, c 中 unsigned char* 数据 如何传给java?相关的知识,希望对你有一定的参考价值。
C: unsigned char* ---无符号型 字符数组。
java 需要使用 c 中的 unsigned char* 应该怎么做比较好?
unsigned char* 如何转换 传给java?
new 一个java的string本回答被提问者采纳
使用 Qt/C++ 通过 JNI 调用 Java 代码。 FindClass 找不到类
【中文标题】使用 Qt/C++ 通过 JNI 调用 Java 代码。 FindClass 找不到类【英文标题】:Using Qt/C++ to call Java code through JNI. FindClass does not find class 【发布时间】:2013-12-31 03:39:01 【问题描述】:我是 JNI 的新手,这是我第一个尝试从 C++ 调用 Java 代码的程序。我正在使用 Qt 5.2,并且正在编写一个 Android 应用程序。
我无法找到我的 java 类并将其加载到我的 C++ 程序中。我在这里阅读了很多关于堆栈溢出和其他地方的帖子,这似乎是一个常见问题,但我还没有能够解决我的问题..
我也不确定是否正确设置了 Java VM,因为 QAndroidJniEnvironment 上的 Qt 文档很少。
我正在寻找有关如何找到我的 java 类的解决方案。我也很欣赏对代码其他部分的一般反馈(我认为可能会有更多错误)。
错误信息:
Starting remote process.D/dalvikvm(24911): GC_CONCURRENT freed 384K, 5% free 9180K/9596K, paused 1ms+2ms, total 15ms
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libgnustl_shared.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libgnustl_shared.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libgnustl_shared.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Core.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Core.so 0x428b2360
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Network.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Network.so 0x428b2360
I/Qt (24911): Network start
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Qml.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Qml.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5Qml.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Gui.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Gui.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5Gui.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Quick.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5Quick.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5Quick.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5AndroidExtras.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5AndroidExtras.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/data/org.qtproject.example.AndroidTest/lib/libQt5AndroidExtras.so 0x428b2360, skipping init
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/plugins/platforms/android/libqtforandroidGL.so 0x428b2360
D/dalvikvm(24911): Added shared lib /data/data/org.qtproject.example.AndroidTest/plugins/platforms/android/libqtforandroidGL.so 0x428b2360
I/Qt (24911): qt start
W/dalvikvm(24911): dvmFindClassByName rejecting 'org/qtproject/qt5/android/QtMessageDialogHelper'
D/dalvikvm(24911): Trying to load lib /data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so 0x428b2360
D/dalvikvm(24911): Shared lib '/data/data/org.qtproject.example.AndroidTest/lib/libQt5QuickParticles.so' already loaded in same CL 0x428b2360
D/dalvikvm(24911): Trying to load lib /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b2360
D/Qt (24911): qml\qqmlengine.cpp:1451 (QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool)): QML debugging is enabled. Only use this in a safe environment.
D/dalvikvm(24911): Added shared lib /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b2360
D/dalvikvm(24911): No JNI_OnLoad found in /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b2360, skipping init
W/Qt (24911): kernel\qcoreapplication.cpp:416 (QCoreApplicationPrivate::QCoreApplicationPrivate(int&, char**, uint)): WARNING: QApplication was not created in the main() thread.
W/dalvikvm(24911): dvmFindClassByName rejecting 'org/qtproject/qt5/android/QtNativeInputConnection'
W/dalvikvm(24911): dvmFindClassByName rejecting 'org/qtproject/qt5/android/QtExtractedText'
I/Adreno-EGL(24911): <qeglDrvAPI_eglInitialize:320>: EGL 1.4 QUALCOMM Build: I0404c4692afb8623f95c43aeb6d5e13ed4b30ddbDate: 11/06/13
D/Qt (24911): fontdatabases\basic\qbasicfontdatabase.cpp:246 (static QStringList QBasicFontDatabase::addTTFile(const QByteArray&, const QByteArray&)): FT_New_Face failed with index 0 : 90
D/Qt (24911): ..\AndroidTest\jnimathcppwrapper.cpp:18 (jniMathCppWrapper::jniMathCppWrapper()): JniMath class not found
D/Qt (24911): ..\AndroidTest\jnimathcppwrapper.cpp:43 (int jniMathCppWrapper::eleven()): Enter eleven
F/libc (24911): Fatal signal 11 (SIGSEGV) at 0x0000002c (code=1), thread 24933 (ple.AndroidTest)
Java 类:
package org.app.test;
public class JniMath
public JniMath()
public int eleven()
return 11;
.pro 文件:
# Add more folders to ship with the application, here
folder_01.source = qml/AndroidTest
folder_01.target = qml
DEPLOYMENTFOLDERS = folder_01
# Additional import path used to resolve QML modules in Creator's code model
QML_IMPORT_PATH =
# The .cpp file which was generated for your project. Feel free to hack it.
SOURCES += main.cpp #\
# jnimathcppwrapper.cpp
# Installation path
# target.path =
# Please do not modify the following two lines. Required for deployment.
include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
qtcAddDeployment()
RESOURCES += \
resources.qrc
QT += androidextras
OTHER_FILES += \
android/src/org/app/test/JniMath.java
HEADERS += #\
# jnimathcppwrapper.h
android
SOURCES += jnimathcppwrapper.cpp
HEADERS += jnimathcppwrapper.h
main.cpp:
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include "jnimathcppwrapper.h"
#include <QDebug>
#include <QString>
int main(int argc, char *argv[])
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/AndroidTest/main.qml"));
viewer.showExpanded();
jniMathCppWrapper *test = new jniMathCppWrapper();
qDebug() << QString::number(test->eleven());
return app.exec();
jnimathcppwrapper.h:
#ifndef JNIMATHCPPWRAPPER_H
#define JNIMATHCPPWRAPPER_H
#include <QtAndroidExtras>
class jniMathCppWrapper
public:
jniMathCppWrapper();
int eleven();
private:
jobject jniMathObject;
;
#endif // JNIMATHCPPWRAPPER_H
jnimathcppwrapper.cpp:
#include "jnimathcppwrapper.h"
#include <QtAndroidExtras>
#include <QDebug>
#include <jni.h>
static jclass jniMathClassID = 0;
static jmethodID jniMathConstructorMethodID = 0;
static jmethodID jniMathElevenMethodID = 0;
jniMathCppWrapper::jniMathCppWrapper()
QAndroidJniEnvironment qjniEnv;
//Get JniMath class ID.
jniMathClassID = qjniEnv->FindClass("android/src/org/app/test/JniMath");
if(jniMathClassID == NULL)
qDebug() << "JniMath class not found";
return;
//Get constructor method ID
jniMathConstructorMethodID = qjniEnv->GetMethodID(jniMathClassID, "<init>", "void(V)");
if(jniMathConstructorMethodID == NULL)
qDebug() << "JniMath constructor not found";
return;
//Create new Java object and calling the selected constructor.
jniMathObject = qjniEnv->NewObject(jniMathClassID, jniMathConstructorMethodID);
if(jniMathObject == NULL)
qDebug() << "JniMath Java object could not be constructed";
return;
int jniMathCppWrapper::eleven()
QAndroidJniEnvironment qjniEnv;
qDebug() << "Enter eleven";
//Get eleven method ID
jniMathElevenMethodID = qjniEnv->GetMethodID(jniMathClassID, "eleven", "void(V)");
if(jniMathElevenMethodID == NULL)
qDebug() << "JniMath class, eleven method not found";
return 9;
jint res = qjniEnv->CallIntMethod(jniMathObject, jniMathElevenMethodID);
return (int) res;
项目结构:
编辑:
我还尝试了导致相同错误的不同方法:
QAndroidJniObject *myJavaClass = new QAndroidJniObject("android/src/org/app/test/JniMath");
if(myJavaClass->isValid())
qDebug() << "Class found!";
else
qDebug() << "Class NOT found!";
当尝试加载 java/lang/String 时,上面的两个方法都找到了类。
编辑:
错误日志:
D/Qt ( 3385): qml\qqmlengine.cpp:1451 (QQmlDebuggingEnabler::QQmlDebuggingEnabler(bool)): QML debugging is enabled. Only use this in a safe environment.
D/dalvikvm( 3385): Added shared lib /data/app-lib/org.qtproject.example.AndroidTest-1/libAndroidTest.so 0x428b67f8
D/Qt ( 3385): ..\AndroidTest\jnimathcppwrapper.cpp:68 (jint JNI_OnLoad(JavaVM*, void*)): Class NOT found
D/AndroidRuntime( 3385): Shutting down VM
W/dalvikvm( 3385): threadid=1: thread exiting with uncaught exception (group=0x41fecba8)
E/AndroidRuntime( 3385): FATAL EXCEPTION: main
E/AndroidRuntime( 3385): Process: org.qtproject.example.AndroidTest, PID: 3385
E/AndroidRuntime( 3385): java.lang.NoClassDefFoundError: org/app/test/JniMath
E/AndroidRuntime( 3385): at java.lang.Runtime.nativeLoad(Native Method)
E/AndroidRuntime( 3385): at java.lang.Runtime.doLoad(Runtime.java:421)
E/AndroidRuntime( 3385): at java.lang.Runtime.loadLibrary(Runtime.java:362)
E/AndroidRuntime( 3385): at java.lang.System.loadLibrary(System.java:526)
E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.loadApplication(QtActivity.java:235)
E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.startApp(QtActivity.java:522)
E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.onCreate(QtActivity.java:744)
E/AndroidRuntime( 3385): at android.app.Activity.performCreate(Activity.java:5231)
W/dalvikvm( 3385): threadid=1: thread exiting with uncaught exception (group=0x41fecba8)
E/AndroidRuntime( 3385): FATAL EXCEPTION: main
E/AndroidRuntime( 3385): Process: org.qtproject.example.AndroidTest, PID: 3385
E/AndroidRuntime( 3385): java.lang.NoClassDefFoundError: org/app/test/JniMath
E/AndroidRuntime( 3385): at java.lang.Runtime.nativeLoad(Native Method)
E/AndroidRuntime( 3385): at java.lang.Runtime.doLoad(Runtime.java:421)
E/AndroidRuntime( 3385): at java.lang.Runtime.loadLibrary(Runtime.java:362)
E/AndroidRuntime( 3385): at java.lang.System.loadLibrary(System.java:526)
E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.loadApplication(QtActivity.java:235)
E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.startApp(QtActivity.java:522)
E/AndroidRuntime( 3385): at org.qtproject.qt5.android.bindings.QtActivity.onCreate(QtActivity.java:744)
E/AndroidRuntime( 3385): at android.app.Activity.performCreate(Activity.java:5231)
E/AndroidRuntime( 3385): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
E/AndroidRuntime( 3385): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
E/AndroidRuntime( 3385): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
E/AndroidRuntime( 3385): at android.app.ActivityThread.access$800(ActivityThread.java:135)
E/AndroidRuntime( 3385): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
E/AndroidRuntime( 3385): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime( 3385): at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime( 3385): at android.app.ActivityThread.main(ActivityThread.java:5017)
E/AndroidRuntime( 3385): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 3385): at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime( 3385): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
E/AndroidRuntime( 3385): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
E/AndroidRuntime( 3385): at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 3385): Caused by: java.lang.ClassNotFoundException: Didn't find class "org.app.test.JniMath" on path: DexPathList[[zip file "/data/app/org.qtproject.example.AndroidTest-1.apk"],nativeLibraryDirectories=[/data/app-lib/org.qtproject.example.AndroidTest-1, /vendor/lib, /system/lib]]
E/AndroidRuntime( 3385): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
E/AndroidRuntime( 3385): at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
E/AndroidRuntime( 3385): at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
E/AndroidRuntime( 3385): ... 21 more
评论:为什么这个问题不是重复的(作者 Alex Cohn)
毫无疑问,这里的根本问题与FindClass from any thread in Android JNI中的相同,但这里提出的问题是一个非常不同的问题,IMO。 author 不是在寻找从本机线程访问 ClassLoader 的通用方法。他(或她)正在寻找一种简单有效的方法来从基于 Qt 的本机代码访问 Java 回调。因此,所有关于类加载器如何在 Android 中工作以及如何对其进行修补的讨论对他来说都是无关紧要的。 如果作者不这么认为,我很乐意同意以重复的形式结束这个问题
更新:这个问题甚至与 JNI 线程无关
请考虑之前的评论无效。这个问题与多线程无关。这完全是关于如何设置一个 Android Qt 应用程序,以便它可以使用自定义 Java 类,类似于 sample。
【问题讨论】:
@AlexCohn:我正在寻找一种 Qt 方式来执行此操作,因为现在 QAndroidJniObject 和 QAndroidJniEnvironment 类可用。我还没有找到任何这样做的好例子。正如我所提到的,我以前根本没有使用过 JNI,所以这对我来说是全新的。 很遗憾,您的问题超出了 Qt 模型... 我现在相信您的问题与链接的文章无关。您的问题不是您从辅助线程尝试 JNI,而是您必须设置 Qt Android 应用程序,以便它实际上知道您要使用的 Java 类。如果您查看sample project,您会看到涉及到文件 AndroidManifest.xml。对不起,这超出了我的专业范围。 在您的允许下,我将删除我现在认为与您的事业完全无关的“答案”。 @AlexCohn:我同意。我在做我想做的事方面取得了一些进展。我会更新我的问题并在完成后给出答案。 【参考方案1】:我用这个例子http://www.gnuton.org/blog/2014/01/invoking-qtc-code-from-the-java-side-of-qt-for-android-application/
我就是这样做的。 在我的 java 主类中,我添加了一个静态方法来调用相同的活动(因为它必须是静态的):
static public void startFacebookActivity()
String msgTag = "FACEBOOK_APP";
try
Log.v(msgTag, "starting activity");
Activity mother = QtNative.activity();
Log.v(msgTag, mother.toString());
Log.v(msgTag, MainActivity.class.getName());
Intent intent = new Intent(mother, MainActivity.class);
mother.startActivity(intent);
catch (Exception e)
Log.e(msgTag, e.toString());
e.printStackTrace();
然后在我的头文件中添加了这个:
class FacebookAndroid : public QObject
Q_OBJECT
public:
FacebookAndroid(QObject *parent = 0);
public slots:
void startAndroidFacebook();
;
在我的 cpp 文件中,我只是像这样调用了我的 java 方法:
void FacebookAndroid::startAndroidFacebook()
QAndroidJniObject::callStaticMethod<void>("org.qtproject.example.MainActivity",
"startFacebookActivity",
"()V");
【讨论】:
【参考方案2】:你的java源码目录是复制到android-build目录下了吗?您的源文件夹中的 android 文件夹需要在 qmake 变量 ANDROID_PACKAGE_SOURCE_DIR 中列出,请参阅:http://qt-project.org/doc/qt-5/deployment-android.html#qmake-variables
【讨论】:
【参考方案3】:让 FindClass 工作的最简单方法是从 JNI_OnLoad 函数中调用它。 JNI 会在加载时在正确的线程中自动调用此函数。旧版本的 notificationclient 示例在提交 #6500083 之前使用了此方法。这是androidjnibindings.cpp文件相关部分的总结:
#include <QtAndroidExtras/QJNIObject>
jint JNICALL JNI_OnLoad(JavaVM *vm, void *)
JNIEnv *env;
if (vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_4) != JNI_OK)
qFatal("Couldn't initialize environment!");
return -1;
jclass clazz = env->FindClass("org/qtproject/example/notification/NotificationClient");
if (clazz == 0)
//
return JNI_VERSION_1_4;
这不在 5.2 示例代码中,因为不再需要从 C++ 代码调用 Java,但我不知道显示从 Java 调用 C 的 QT5.2 示例。
【讨论】:
【参考方案4】:jniMathClassID = qjniEnv->FindClass("android/src/org/app/test/JniMath");
尝试给出包名:“org/app/test/JniMath”,而不是“android/src/org/app/test/JniMath”并将其放入
jint JNI_OnLoad(JavaVM *vm, void *reserved)
JNIEnv* env;
if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK)
qCritical()<<"Can't get the enviroument";
return -1;
s_javaVM = vm; // cache the JavaVM pointer
jclass clazz= env->FindClass("org/app/test/JniMath");
jniMathClassID = (jclass)env->NewGlobalRef(tmp);
这样的……
【讨论】:
以上是关于java jni 调用 c 代码, c 中 unsigned char* 数据 如何传给java?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Qt/C++ 通过 JNI 调用 Java 代码。 FindClass 找不到类
我的C/C++语言学习进阶之旅转载:实现一个在JNI中调用Java对象的工具类
01_JNI是什么,为什么使用,怎么用JNI,Cygwin环境变量配置,NDK案例(使用Java调用C代码),javah命令使用