Gast
2012-04-04, 12:12:01
Hallo,
ich habe folgendes Problem mit Cygwin. Ich habe eine Java-Klasse mit einer nativen Methode:
package de.jni.test;
public class JniClass {
public static native double processArray(double[] array);
}
die per JNI in C ausgeführt werden soll. Auf der C-Seite ist die Methode/Funktion folgendermaßen implementiert:
JNIEXPORT jdouble JNICALL Java_de_jni_test_JniClass_processArray
(JNIEnv * env, jobject obj, jdoubleArray array_J)
{
// get size of Java array
int size = (*env)->GetArrayLength(env, array_J);
// create C array of same size
double *array_C = (double*) malloc(size * sizeof(double));
// copy elements from Java array to C array
(*env)->GetDoubleArrayRegion(env, array_J, 0, size, array_C);
// do some funny stuff to C array
double sum = 0;
int i;
for (i=0; i < size; i++)
{
sum += array_C[i];
array_C[i] += sum;
}
// copy back elements from C array to Java array
(*env)->SetDoubleArrayRegion(env, array_J, 0, size, array_C);
// release C array
free(array_C);
return sum;
}
Es wird also der Inhalt des übergebenen Java-Arrays in ein C-Array kopiert, das mit malloc erzeugt wird. Mit den Elementen des C-Arrays wird dann etwas gemacht, und anschließend werden sie in das Java-Array zurückkopiert. Das C-Array wird dann freigegeben.
Das ganz funktioniert auch wunderbar, wenn ich die C-DLL mit MinGW kompiliere. Baue ich sie stattdessen mit Cygwin, so stürzt bei Aufruf der Methode auf Java-Seite die JVM ab, mit folgender Fehlermeldung:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x610d3494, pid=4576, tid=6784
#
# JRE version: 6.0_20-b02
# Java VM: Java HotSpot(TM) Client VM (16.3-b01 mixed mode windows-x86 )
# Problematic frame:
# C [cygwin1.dll+0xd3494]
#
# An error report file with more information is saved as:
# C:\Users\scholten\workspace\JniTest_Java\hs_err_pid4576.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Offenbar scheint das Problem von malloc herzurühren, denn wenn ich die Funktion in C stattdessen folgendermaßen implementiere:
JNIEXPORT jdouble JNICALL Java_de_jni_test_JniClass_processArray
(JNIEnv * env, jobject obj, jdoubleArray array_J)
{
// size of Java array
int size = (*env)->GetArrayLength(env, array_J);
// create C array and copy elements from Java array
(*env)->GetDoubleArrayElements(env, array_J, NULL);
// do some funny stuff to C array
double sum = 0;
int i;
for (i=0; i < size; i++)
{
sum += array_C[i];
array_C[i] += sum;
}
// copy back elements from C array to Java array and release C array
(*env)->ReleaseDoubleArrayElements(env, array_J, array_C, 0);
return sum;
}
d.h. ohne malloc() und free(), und dafür stattdessen mit den von JNI gelieferten Funktionen zum Erzeugen und Freigeben von C-Arrays, dann klappt alles auch unter Cygwin.
Leider kann ich auf malloc() nicht verzichten und auch nicht MinGW statt Cygwin benutzen, da ich eine C-Bibliothek per JNI ansprechen muss, die nur unter Cygwin kompilierfähig ist, und die massiven Gebrauch von malloc macht.
Jemand eine Idee?
Danke im voraus.
ich habe folgendes Problem mit Cygwin. Ich habe eine Java-Klasse mit einer nativen Methode:
package de.jni.test;
public class JniClass {
public static native double processArray(double[] array);
}
die per JNI in C ausgeführt werden soll. Auf der C-Seite ist die Methode/Funktion folgendermaßen implementiert:
JNIEXPORT jdouble JNICALL Java_de_jni_test_JniClass_processArray
(JNIEnv * env, jobject obj, jdoubleArray array_J)
{
// get size of Java array
int size = (*env)->GetArrayLength(env, array_J);
// create C array of same size
double *array_C = (double*) malloc(size * sizeof(double));
// copy elements from Java array to C array
(*env)->GetDoubleArrayRegion(env, array_J, 0, size, array_C);
// do some funny stuff to C array
double sum = 0;
int i;
for (i=0; i < size; i++)
{
sum += array_C[i];
array_C[i] += sum;
}
// copy back elements from C array to Java array
(*env)->SetDoubleArrayRegion(env, array_J, 0, size, array_C);
// release C array
free(array_C);
return sum;
}
Es wird also der Inhalt des übergebenen Java-Arrays in ein C-Array kopiert, das mit malloc erzeugt wird. Mit den Elementen des C-Arrays wird dann etwas gemacht, und anschließend werden sie in das Java-Array zurückkopiert. Das C-Array wird dann freigegeben.
Das ganz funktioniert auch wunderbar, wenn ich die C-DLL mit MinGW kompiliere. Baue ich sie stattdessen mit Cygwin, so stürzt bei Aufruf der Methode auf Java-Seite die JVM ab, mit folgender Fehlermeldung:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x610d3494, pid=4576, tid=6784
#
# JRE version: 6.0_20-b02
# Java VM: Java HotSpot(TM) Client VM (16.3-b01 mixed mode windows-x86 )
# Problematic frame:
# C [cygwin1.dll+0xd3494]
#
# An error report file with more information is saved as:
# C:\Users\scholten\workspace\JniTest_Java\hs_err_pid4576.log
#
# If you would like to submit a bug report, please visit:
# http://java.sun.com/webapps/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Offenbar scheint das Problem von malloc herzurühren, denn wenn ich die Funktion in C stattdessen folgendermaßen implementiere:
JNIEXPORT jdouble JNICALL Java_de_jni_test_JniClass_processArray
(JNIEnv * env, jobject obj, jdoubleArray array_J)
{
// size of Java array
int size = (*env)->GetArrayLength(env, array_J);
// create C array and copy elements from Java array
(*env)->GetDoubleArrayElements(env, array_J, NULL);
// do some funny stuff to C array
double sum = 0;
int i;
for (i=0; i < size; i++)
{
sum += array_C[i];
array_C[i] += sum;
}
// copy back elements from C array to Java array and release C array
(*env)->ReleaseDoubleArrayElements(env, array_J, array_C, 0);
return sum;
}
d.h. ohne malloc() und free(), und dafür stattdessen mit den von JNI gelieferten Funktionen zum Erzeugen und Freigeben von C-Arrays, dann klappt alles auch unter Cygwin.
Leider kann ich auf malloc() nicht verzichten und auch nicht MinGW statt Cygwin benutzen, da ich eine C-Bibliothek per JNI ansprechen muss, die nur unter Cygwin kompilierfähig ist, und die massiven Gebrauch von malloc macht.
Jemand eine Idee?
Danke im voraus.