JNI segfaults创建新对象 [英] JNI segfaults creating new object

查看:60
本文介绍了JNI segfaults创建新对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是JNI(和Java)的新手,所以如果这只是一个愚蠢的错误,我事先表示歉意.但是经过大量搜索,我找不到解释或解决方案.

I'm new to JNI (and java), so I apologize in advance if this is just a stupid mistake. But after much searching I can't find an explanation or a solution.

我有一个名为 Tagged< T> 的参数Java类. Tagged< T> 的Java构造函数采用一个对象 T 和一个长的 ptr .C代码具有一个值,并且应该使用 v 值和该值的内存地址创建一个Tagged对象.但是,当我调用NewObject时遇到段错误.不确定问题是否出在泛型Type构造函数(用整数调用),Java/C整数类型之间的不匹配(长对长,长对长),愚蠢的错误或我未曾考虑的东西.

I have a parametric Java class called Tagged<T>. The Java constructor for Tagged<T> takes an object T and a long ptr. The C code has a value and is supposed to create a Tagged object with the value v and the memory address of that value. However, I get a segfault when I call NewObject. Not sure if the problem is the generic Type constructor (called with an integer), a mismatch between Java/C integer types (long vs long long vs long), a stupid mistake, or something I haven't considered.

Java类:

public class Tagged<T> {
    private final T value;
    private long ptr;

    private TaggedValue(T value, long ptr){
        this.value = value;
        this.ptr = ptr;
    }
}

JNI代码:

JNIEXPORT jobject JNICALL Java_package_Class_function (JNIEnv * env, jclass cls, ...){

  // Find Java class
  jclass c = (*env)->FindClass(env, "package/Tagged");
  if (c == 0) {
      printf("Find Class Failed.\n");
  }else{
      printf("Found class.\n");
  }

  // Find Tagged<T> constructor
  jmethodID constructor = (*env)->GetMethodID(env,c, "<init>", "(Ljava/lang/Object;J)V");
  if (constructor == 0) {
      printf("Find method Failed.\n");
  } else {
      printf("Found method.\n");
  }

  // Get value 
  int * valptr = LibraryCall();

  // check that constructor arguments are what we expect
  int val = (int) *valptr;
  printf("Value:  %i\n",val);
  long long addr = (long long) valptr;
  printf("Address: %p = %lld = %p\n",valptr,addr,(void *)addr);

  // Try to create Tagged object
  jobject taggedval = (*env)->NewObject(env, c, constructor, val, addr);
  printf("We never get here\n");

  return taggedval;
}

控制台输出:

Found class.
Found method.
Value:  102583
Address: 0x7fdcc2d209b0 = 140586138077616 = 0x7fdcc2d209b0
#
# A fatal error has been detected by the Java Runtime Environment: 
#
#  SIGSEGV (0xb) at pc=0x0000000109ae9bcf, pid=42140, tid=3847
#
# JRE version: Java(TM) SE Runtime Environment (8.0_66-b17) (build 1.8.0_66-b17)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode bsd-amd64 compressed oops)
# Problematic frame:
# V  [libjvm.dylib+0x2e9bcf]  JavaCallArguments::parameters()+0x27
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /Users/eleanor/Documents/workspace/av-java/src/hs_err_pid42140.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.java.com/bugreport/crash.jsp
#
Abort trap: 6

感谢任何/所有帮助!

推荐答案

您的构造函数使用 jobject long ,然后将其传递给 int long long .

Your constructor takes an jobject and a long, and you are passing it an int and a long long.

也许您可能打算将 int 包装到Java Integer 中?而且,您也应该将long转换为 jlong​​ ,以防 long long jlong​​ 相同类型.

Maybe you probably meant to wrap the int into a java Integer? And you should probably cast the long to a jlong too, just in case long long and jlong arent the same type.

这篇关于JNI segfaults创建新对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆