如何使用JNI从C语言中的Oobject获取对象的fieldID?

huangapple go评论83阅读模式
英文:

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&#39;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&#39;t recognize.

I&#39;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&#39;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(&quot;native-lib&quot;);
}

@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&#39;t find a way to debug this s***.

The path/signature was generated by Android Studio itself and I can&#39;t find a reason, why it should be wrong.

Does anyone here can see anything that crashes the app here?


edit: I&#39;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.

huangapple
  • 本文由 发表于 2020年10月14日 01:05:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/64339880.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定