使用 JNI (C++) 从本机线程调用 Java 方法时遇到问题
我有一个 JNI 问题,希望有人能帮助我解决。
我正在尝试从本机线程调用名为 LUSOutputJNI 的 Java 类的构造函数。
它在这个特定类的 FindClass(...) 上一直失败。
代码如下:
LOGE("1");
JNIEnv *env = NULL;
LOGE("2");
int res = -1;
res = g_vm->AttachCurrentThread(&env, NULL);
if(env == NULL)
{
LOGE("env is NULL, AttachCurrentThread failed");;
}
if(res >= 0)
LOGE("AttachCurrentThread was successful");
jclass clazz = NULL;
jmethodID cid;
jclass clazzESEngine;
jmethodID callbackid;
jobject jCoreOut;
static jfieldID fid_ActionState = NULL;
static jfieldID fid_nSpeed = NULL;
static jfieldID fid_nType = NULL;
static jfieldID fid_nInProcess = NULL;
static jfieldID fid_nX = NULL;
static jfieldID fid_nY = NULL;
LOGE("3");
static const char* const ECOClassName = "lus/android/sdk/LUSOutputJNI";
//static const char* const ECOClassName = "android/widget/TextView";
clazz = env->FindClass(ECOClassName);
if (clazz == NULL) {
LOGE("Can't find class LUSOutputJNI");
}
else
LOGE("lus/android/sdk/LUSOutputJNI was found, YEY!!");
LOGE("4");
cid = env->GetMethodID(clazz,"<init>", "()V");
LOGE("5");
jCoreOut = env->NewObject(clazz, cid);
LOGE("6");
这是失败时的 logcat 输出:
E/lusCore_JNI( 3040): 1
E/lusCore_JNI( 3040): 2
E/lusCore_JNI( 3040): AttachCurrentThread was successful
E/lusCore_JNI( 3040): 3
E/lusCore_JNI( 3040): Can't find class LUSOutputJNI
E/lusCore_JNI( 3040): 4
W/dalvikvm( 3040): JNI WARNING: JNI method called with exception raised
观察:
- 我从 AttachCurrentThread 得到的结果是 0,这意味着此附件成功 + env 指针不再为 NULL。
- 我确信 LUSOutputJNI 的包名称声明(三次检查...)
- 当我尝试使用更流行的类名称(例如 android/widget/TextView )运行 FindClass(..) 时,我得到了肯定的匹配。它就在那里。这意味着线程附件和环境变量都正常。 (我可以这样假设吗?)
- 当我尝试从具有 JNI 线程运行的 JNI 方法运行以下代码时,它发现 LUSOutputJNI 类没有问题。
我做错了什么?
非常感谢您的帮助:)
感谢您的宝贵时间,
Ita
I have a JNI problem which I hope someone can help me out with.
I'm trying to call on a constructor of a Java class called LUSOutputJNI from a native thread.
It keeps failing on FindClass(...) of this specific class.
Here is the code:
LOGE("1");
JNIEnv *env = NULL;
LOGE("2");
int res = -1;
res = g_vm->AttachCurrentThread(&env, NULL);
if(env == NULL)
{
LOGE("env is NULL, AttachCurrentThread failed");;
}
if(res >= 0)
LOGE("AttachCurrentThread was successful");
jclass clazz = NULL;
jmethodID cid;
jclass clazzESEngine;
jmethodID callbackid;
jobject jCoreOut;
static jfieldID fid_ActionState = NULL;
static jfieldID fid_nSpeed = NULL;
static jfieldID fid_nType = NULL;
static jfieldID fid_nInProcess = NULL;
static jfieldID fid_nX = NULL;
static jfieldID fid_nY = NULL;
LOGE("3");
static const char* const ECOClassName = "lus/android/sdk/LUSOutputJNI";
//static const char* const ECOClassName = "android/widget/TextView";
clazz = env->FindClass(ECOClassName);
if (clazz == NULL) {
LOGE("Can't find class LUSOutputJNI");
}
else
LOGE("lus/android/sdk/LUSOutputJNI was found, YEY!!");
LOGE("4");
cid = env->GetMethodID(clazz,"<init>", "()V");
LOGE("5");
jCoreOut = env->NewObject(clazz, cid);
LOGE("6");
Here is the logcat output from when it fails:
E/lusCore_JNI( 3040): 1
E/lusCore_JNI( 3040): 2
E/lusCore_JNI( 3040): AttachCurrentThread was successful
E/lusCore_JNI( 3040): 3
E/lusCore_JNI( 3040): Can't find class LUSOutputJNI
E/lusCore_JNI( 3040): 4
W/dalvikvm( 3040): JNI WARNING: JNI method called with exception raised
Observations:
- I get a result from AttachCurrentThread which is 0, which means that this attachment was successful + the env pointer is no longer NULL.
- I'm sure about the package name declaration of LUSOutputJNI (triple checked it...)
- When I try to run FindClass(..) with a more popular class name such as android/widget/TextView , I get a positive match. It is there. Meaning the thread attachment and the env variables are ok. (Can I assume that?)
- When I try to run the following code from a JNI method which has a JNI thread running it, it finds the LUSOutputJNI class without a problem.
What am I doing wrong?
Help will be much appreciated :)
Thanks for your time,
Ita
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在这里找到答案\解决方法。 (查找常见问题解答:“FindClass 未找到我的课程”
JNI 提示)
我基本上保存了一个全局引用到所需的 jclass 对象。
然而,为了使代码能够编译,必须克服 C/JNI 和 C++/JNI 之间的一些邪恶的 JNI 更改。
这就是我编译和工作 NewGlobalRef 的方法。
我希望这对任何人都有帮助。
Found the answer \ work around in here. (Look for FAQ: "FindClass didn't find my class" in
JNI tips)
I basicaly saved a global ref to the needed jclass objects.
Did however had to overcome some evil JNI changes between C/JNI and C++/JNI in order for the code to compile.
This is how I got the NewGlobalRef to compile and work.
I hope this helps anyone.
要获得有关发生问题的更多信息(它将记录到 stderr,而不是 LOGE,我不知道如何更改它),您可以添加一些异常打印 - 您可以更改此:
为此:
To get a bit more information about whats going wrong ( it will log to stderr, not LOGE, and I'm not sure how to change that) you can add some exception printing - you can change this:
To this: