Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JNI从同一源C文件Java调用函数JNI_Java_Function_Exception_Java Native Interface - Fatal编程技术网

JNI从同一源C文件Java调用函数JNI

JNI从同一源C文件Java调用函数JNI,java,function,exception,java-native-interface,Java,Function,Exception,Java Native Interface,我有下面的代码,我想调用在同一源文件中实现的函数,在本例中使用C语言: JNIEXPORT jstring JNICALL MyClass_get_1Uname__C (JNIEnv *env, jclass class, jchar mode) { return (*env)->NewStringUTF(env, "UsingStringC.get_Uname With Parameter"); } JNIEXPORT jstring JNICALL MyClass_get_1Un

我有下面的代码,我想调用在同一源文件中实现的函数,在本例中使用C语言:

JNIEXPORT jstring JNICALL MyClass_get_1Uname__C (JNIEnv *env, jclass class, jchar mode) {
  return (*env)->NewStringUTF(env, "UsingStringC.get_Uname With Parameter");
}

JNIEXPORT jstring JNICALL MyClass_get_1Uname__ (JNIEnv *env, jclass class) {
  printf("Attended by:get_1Uname__\nPassing to:get_1Uname__C\n");
  return MyClass_get_1Uname__C(env,class,'a');
}
问题在Java端不起作用:

  public MyClass() {
    System.out.println("testBefore");
    String S2 = this.get_Uname('s');
    System.out.println(S2);
    System.out.println("testAfter");  // Work!!!
    String S3 = this.get_Uname();  // Access Violation!!!
    System.out.println(S3);
    System.out.println("testFinish");
  }
  native public static String get_Uname(char mode);
  native public static String get_Uname();
  static {
    try { 
     System.loadLibrary("UsingStringC");
    } catch (java.lang.UnsatisfiedLinkError ex){
      System.out.println("ERROR MESSAGE:"+ex.getMessage());
    }
  }
我得到的结果是:

testBefore
UsingStringC.get_Uname With Parameter
testAfter
#
# A fatal error has been detected by the Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x610e9914, pid=4712, tid=8668
#
# JRE version: Java(TM) SE Runtime Environment (8.0_20-b26) (build 1.8.0_20-b26)
# Java VM: Java HotSpot(TM) Client VM (25.20-b23 mixed mode windows-x86 )
# Problematic frame:
# C  [cygwin1.dll+0xe9914]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# D:\Developer\...\hs_err_pid4712.log
#
# If you would like to submit a bug report, please visit:
#   http://bugreport.sun.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Java Result: 1
BUILD SUCCESSFUL (total time: 6 seconds)
我不知道如何在同一个源文件中调用包含(声明)的函数

如何执行此操作

.h文件(标题)

.c文件(源)

Java代码


在OS X上,只要对代码进行少量清理,就完全没有问题:

H代码:

#include "jni.h"

/*
 * Class:     MyClass
 * Method:    get_Uname
 * Signature: (C)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_MyClass_get_1Uname__C (JNIEnv *, jclass, jchar);

/*
 * Class:     MyClass
 * Method:    get_Uname
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_MyClass_get_1Uname__ (JNIEnv *, jclass);

int add(int , int);
int dif(int , int);
C代码:

#include "jni.h"

JNIEXPORT jstring JNICALL Java_MyClass_get_1Uname__C (JNIEnv *env, jclass class, jchar mode) {


if (mode == 'a' || mode == 'A' ) {
    printf( "Addition %i\n", add(15, 10));
  } else {
    printf( "Difference %i\n", dif(15, 10));
  }
  return (*env)->NewStringUTF(env, "UsingStringC.get_Uname With Parameter");
}

JNIEXPORT jstring JNICALL Java_MyClass_get_1Uname__ (JNIEnv *env, jclass class) {
  printf("Attended by:get_1Uname__\nPassing to:get_1Uname__C\n");
  return Java_MyClass_get_1Uname__C(env,class,'a');
}

int add(int a, int b) {
  int c = (a+b);
  printf("Adding\n");
  return c;
}
int dif(int a, int b) {
  int c = (a-b);
  printf("Differing\n");
  return c;
}
Java代码:

public class MyClass {
        public static void main(String [] arg) {
                MyClass cls = new MyClass();
                cls.test();
        }
        public void test() {
            System.out.println("testBefore");  // Works!!!
            String S2 = this.get_Uname('s');   // Works
            System.out.println(S2);
            System.out.println("testAfter");
            String S3 = this.get_Uname();      // Works
            System.out.println(S3);
            System.out.println("testFinish");
        }
        native public static String get_Uname(char mode);
        native public static String get_Uname();
        static {
                try {
                        System.loadLibrary("Simple");
                } catch (java.lang.UnsatisfiedLinkError ex){
                        System.out.println("ERROR MESSAGE:"+ex.getMessage());
                }
        }
}
C汇编:

cc -g -shared -fpic -I${JAVA_HOME}/include \ 
  -I${JAVA_HOME}/include/darwin simple.c \
  -o libSimple.dylib
javac MyClass.java
Java编译:

cc -g -shared -fpic -I${JAVA_HOME}/include \ 
  -I${JAVA_HOME}/include/darwin simple.c \
  -o libSimple.dylib
javac MyClass.java
执行:

export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
java MyClass
输出:

testBefore
Differing
Difference 5
UsingStringC.get_Uname With Parameter
testAfter
Attended by:get_1Uname__
Passing to:get_1Uname__C
Adding
Addition 25
UsingStringC.get_Uname With Parameter
testFinish
C编译和库生成的设置是什么?
你的位置在哪里?

为什么?为什么不使用Java中的第二个方法而不是JNI?不要再多写一行JNI了。因为,这个函数需要C很多代码。。。这是一个很小的测试,您只需调试它。附加您选择的调试器并逐步执行,查看C代码崩溃的原因。hs_err文件可能有足够的信息给你提供线索。我不知道如何做,如果你知道请告诉我…@EJP是一个简单的测试来验证这个简单的代码是否工作,不是目标只有执行这个代码。。。
testBefore
Differing
Difference 5
UsingStringC.get_Uname With Parameter
testAfter
Attended by:get_1Uname__
Passing to:get_1Uname__C
Adding
Addition 25
UsingStringC.get_Uname With Parameter
testFinish