英文:
How to get fieldID of Object from Oobject in C using JNI?
问题
我非常抱歉再次提出这个话题。由于多年来一切的发展,旧的答案可能已过时,或者我的代码中可能有错误我无法识别。
我对Android开发还很陌生,通常使用C / C++ / Python进行开发,这就是我想使用JNI的原因。
我使用Android Studio创建了一个普通的Java本机C++项目,尝试访问一个包含第二个类的类(以及一些整数,可以无问题处理)。我只更改了MainActivity.java和native-lib.cpp。其余部分保持原样,以便更容易进行调试。
我的MainActivity.java代码如下:
package com.ultratest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 调用本地方法的示例
TextView tv = findViewById(R.id.sample_text);
zone_plane plane = new zone_plane();
zone_planes planes = new zone_planes(plane);
int state = initialize(planes);
tv.setText(String.valueOf(state));
}
public static class zone_plane {
}
public static class zone_planes {
zone_plane zone_plane;
zone_planes(zone_plane zone_plane) {
this.zone_plane = zone_plane;
}
}
public native static int initialize(zone_planes planes);
}
而我的native-lib.cpp如下:
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jint JNICALL
Java_com_ultratest_MainActivity_initialize(JNIEnv *env, jclass clazz, jobject planes) {
jclass clsPlanes = env->GetObjectClass(planes);
jfieldID fidZones = env->GetFieldID(clsPlanes, "zone_plane","Lcom/ultratest/MainActivity/zone_plane;");
return 0;
}
然而,在cpp文件返回的最后一行在返回前会出错,我找不到调试这个问题的方法。
路径/签名是由Android Studio自动生成的,我找不到它为什么应该是错误的原因。
这里有没有人能看出任何导致应用程序崩溃的问题?
(以上为翻译内容,请注意代码的准确性可能受到翻译的影响,建议仔细核对。)
<details>
<summary>英文:</summary>
I'm very sorry to come up with this topic again. Since everything developed over the years, old answers might be outdated or something is wrong in my code I couldn't recognize.
I'm new to android developement and usually work with c/c++/python, which is why I want to use the JNI.
I created a regular java native c++ project using Android Studio and tried to access a class that contains a second class (and some intergers, which can be processed without any problems). I changed only the MainAcitvity.java and the native-lib.cpp. The rest was kept original so it's easier for me(us) to debug.
My MainActivity.java code looks like this
package com.ultratest;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
static {
System.loadLibrary("native-lib");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Example of a call to a native method
TextView tv = findViewById(R.id.sample_text);
zone_plane plane = new zone_plane();
zone_planes planes = new zone_planes(plane);
int state = initialize(planes);
tv.setText(String.valueOf(state));
}
public static class zone_plane
{
}
public static class zone_planes
{
zone_plane zone_plane;
zone_planes(zone_plane zone_plane) {
this.zone_plane = zone_plane;
}
}
public native static int initialize(zone_planes planes);
}
while my native-lib.cpp looks like this:
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jint JNICALL
Java_com_ultratest_MainActivity_initialize(JNIEnv *env, jclass clazz, jobject planes) {
jclass clsPlanes = env->GetObjectClass(planes);
jfieldID fidZones = env->GetFieldID(clsPlanes, "zone_plane","Lcom/ultratest/MainActivity/zone_plane;");
return 0;
}
However the last line before the retun of the cpp file returns an error and I can't find a way to debug this s***.
The path/signature was generated by Android Studio itself and I can't find a reason, why it should be wrong.
Does anyone here can see anything that crashes the app here?
edit: I've boiled down the code to the minimal to make it easier to investigate.
</details>
# 答案1
**得分**: 1
我编译了以下最简的Java文件,并使用 `javap -private -s MainActivity` 命令检查了结果:
```java
package com.ultratest;
public class MainActivity {
public static class zone_plane {}
private zone_plane zone_plane;
}
结果显示了对于 zone_plane
的以下内部(也称为二进制)名称:
private com.ultratest.MainActivity$zone_plane zone_plane;
descriptor: Lcom/ultratest/MainActivity$zone_plane;
正如您所看到的,MainActivity 和 zone_plane 之间有一个 $
,而不是 /
。这表示一个内部类,而不是包层次结构。
英文:
I compiled the following minimal java file and inspected the result with javap -private -s MainActivity
:
package com.ultratest;
public class MainActivity {
public static class zone_plane {}
private zone_plane zone_plane;
}
The result showed the following internal (aka binary) name for zone_plane
:
private com.ultratest.MainActivity$zone_plane zone_plane;
descriptor: Lcom/ultratest/MainActivity$zone_plane;
As you see, there is a $
between MainActivity and zone_plane, not a /
. That denotes an inner class instead of a package hierarchy.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论