gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 19:46:31 24 4
gpt4 key购买 nike

我有下面的代码,我想调用在同一个源文件中实现的函数,在本例中使用 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 代码

  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());
}
}

最佳答案

在 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 位置在哪里?

关于java - JNI 从同一源 C 文件、Java 调用函数 JNI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31769750/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com