2013-04-05 3 views
1

c에서 정의 된 함수를 호출하기 위해 JNI를 사용하려고합니다. 정말 이상한데, 왜냐하면 내가 자바 프로그램을 실행할 때 때때로 실수를하고 다른 때를 얻는다. 여기에 그들이있다 :gsl을 사용하는 C 함수가있는 Java JNI.

 82 [main] java (5556) C:\Windows\system32\java.exe: *** fatal error - cygheap base mismatch detected - 0x612708F0/0x17FF08F0. 
This problem is probably due to using incompatible versions of the cygwin DLL. 
Search for cygwin1.dll using the Windows Start->Find/Search facility 
and delete all but the most recent version. The most recent version *should* 
reside in x:\cygwin\bin, where 'x' is the drive on which you have 
installed the cygwin distribution. Rebooting is also suggested if you 
are unable to find another cygwin DLL. 
java.lang.UnsatisfiedLinkError: C:\cygwin\home\Juli▒n\Pruebas_JNI\Caracterizacion.dll: Se realiz▒ un acceso no v▒lido a la ubicaci▒n de memoria 
     at java.lang.ClassLoader$NativeLibrary.load(Native Method) 
     at java.lang.ClassLoader.loadLibrary1(Unknown Source) 
     at java.lang.ClassLoader.loadLibrary0(Unknown Source) 
     at java.lang.ClassLoader.loadLibrary(Unknown Source) 
     at java.lang.Runtime.loadLibrary0(Unknown Source) 
     at java.lang.System.loadLibrary(Unknown Source) 
     at Main.<clinit>(Main.java:6) 
Exception in thread "main" 

Exception in thread "main" java.lang.UnsatisfiedLinkError: Main.caracterizar()[F 
     at Main.caracterizar(Native Method) 
     at Main.main(Main.java:10) 

내가 내가 바로 모든 일을 한 생각, 심지어 내가하지 않은 것 같다 생각했다. 여기

내 C 기능

/* 
* File: main.c 
* Author: OCARDONAM 
* Created on 14 de enero de 2013, 11:46 AM 
*/ 
#include <stdio.h> 
#include <math.h> 
#include <string.h> 
#include <jni.h> 
#include <gsl/gsl_vector.h> 
#include <gsl/gsl_statistics.h> 
#include <gsl/gsl_blas.h> 
#include <gsl/gsl_linalg.h> 
#include "sizedata.h" 
#include "elementary_math_vec.h" 
#include "contar.h" 
#include "media.h" 
#include "Main.h" 


JNIEXPORT jfloatArray JNICALL Java_Main_caracterizar (JNIEnv *env, jclass class) { 
    //variables 
    int n_fil, n1, n2, i; 
    char *filename; 
    //features names 
    double m,T1,T2,T3,T4,T5,T6,T7,T8,T9,T10,T11;//,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11; 
    //load signal and define its size 
    filename = "reg_test.txt"; 
    tamano(filename, &n1, &n2); 
    n_fil = n1-2; 

    gsl_vector * v = gsl_vector_alloc (n_fil); 
    { 
     FILE * f = fopen (filename, "r"); 
     gsl_vector_fscanf (f, v); 
     fclose (f); 
    } 


    // statistics features in time domain 
    double data[n_fil],tmp[n_fil]; 
    for (i = 0; i < n_fil; i++) 
    { 
     data[i] = gsl_vector_get(v,i); 
    } 

    //centered data 
    m = gsl_stats_mean(data, 1, n_fil); 
    for (i = 0; i < n_fil; i++) { 
     data[i] = data[i]-m; 
     gsl_vector_set(v,i,data[i]); 
    } 
    T1 = gsl_stats_mean(data, 1, n_fil); //mean 
    T2 = gsl_stats_sd_m(data, 1, n_fil, T1); //standard deviation  
    T3 = gsl_blas_dnrm2(v)/sqrt(n_fil);//RMS 
    T4 = gsl_stats_skew(data, 1, n_fil); //skewness  
    T5 = gsl_stats_kurtosis(data, 1, n_fil) + 3; //kurtosis 
    T6 = ch_T6(data,n_fil); 
    T7 = ch_T7(data,n_fil); //absolute maximum 
    T8 = T7/T3; //Crest Factor 
    T9 = T7/T6; 
    T10 = ch_T10(data,n_fil,T3);//Shape Factor 
    T11 = ch_T11(data,n_fil,T7); 


    //print a vector 

    jfloat res[1000]; 
    jfloatArray jres; 

    for (i = 0; i < n1-2; i++) { 
     res[i] = (jfloat) gsl_vector_get(v, i); 
    } 
    gsl_vector_free (v); 

    (*env)->SetFloatArrayRegion(env, jres, 0, n1-2, res); 
    return jres; 
} 

이며, 여기에 내가 그것을 호출하는 데 사용하는 자바 코드이다 : 또한

public class Main { 

    public native float[] caracterizar(); 

    static { 
     System.loadLibrary("Caracterizacion"); 
    } 

    public static void main(String args[]) { 
     float ans[] = (new Main()).caracterizar(); 

     for (int i=0 ; i<ans.length ; i++) 
      System.out.println(ans[i]); 
    } 
} 

을, 여기에 내가 컴파일하고 C를 연결하는 데 사용 한 것입니다 프로그램 :

gcc -D__int64="long long" -c -I/cygdrive/c/Program\ Files/Java/jdk1.7.0_11/include/ -I/cygdrive/c/Program\ Files/Java/jdk1.7.0_11/include/win32/ -o Main.o Main.c 

링크 :

gcc -shared -L/usr/local/lib -o Caracterizacion.dll Main.o -lgsl -lgslcblas -lm 

어디서 실수인지 잘 모르겠습니다. 나는 다른 JNI 프로그램을 테스트했으며 제대로 작동하므로 문제는 내가 gsl 라이브러리를 포함하는 방식이라고 생각합니다.

도와 주시면 감사하겠습니다. 고마워요

+0

Linux에서 실행 해 보셨습니까? – stdcall

+0

아니요. 그게 문제라고 생각하세요? –

+0

오류로 인해 환경 오류 및 코딩 오류가 아닌 것처럼 보입니다. Linux와 같은 다른 환경에서 테스트 해 보시기 바랍니다. gcc는 시스템에 기본입니다 ... – stdcall

답변

1

내 생각에 gsl 라이브러리가 컴파일되어 cygwin의 다른 버전에 연결될 수 있습니다. 그리고 main.c 코드가 현재 버전의 cygwin으로 컴파일되면 충돌이 발생합니다. 다음을 시도해보십시오 :

  1. 현재 cygwin 환경을 사용하여 gsl을 다시 작성하십시오.
  2. GSL의 정적 라이브러리에 대한 링크.
  3. msvc를 사용하면 msvc에서 gsl을 컴파일 할 수 있고 visual studio solution을 사용하면 정적 또는 동적 라이브러리를 만들 수 있습니다.
3

프로그램을 cygwin 라이브러리에 실제로 링크시키지 않으려면 cygwin GCC를 사용하지 마십시오. 필요한 경우 cygwin dll을 패키지에 패키지해야합니다.

Windows에서 실행하려면 mingw 컴파일러 (Cygwin에도 패키지가 있지만 Cygwin 독립 바이너리가 생성됩니다) 또는 MSVC 프로젝트를 사용하십시오. Java가 cygwin을 지원하지 않는 한 cygwin 경로를 이해하지 못하지만 원시 코드는 이해할 수 있습니다. 그건 정말 혼란 스러울 것입니다. 필요한 경우를 제외하고는 cygwin을 스크립팅에 사용하고 컴파일러로 mingw-gcc를 사용하여 바이너리를 작성하거나 Min Lin의 스튜디오 프로젝트를 사용하십시오.