JNI从相同的源C文件Java

时间:2015-08-02 07:56:31

标签: 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_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文件(标题)

/*
 * 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文件(来源)

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中的CODE

  public MyClass() {
    System.out.println("testBefore");  // Work!!!
    String S2 = this.get_Uname('s');  // Access Violation!!!
    System.out.println(S2);
    System.out.println("testAfter");
    String S3 = this.get_Uname();
    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());
    }
  }

1 个答案:

答案 0 :(得分:0)

在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

Java编译:

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编译和lib生成的设置是什么? 您在lib位置的位置是什么?