1

cで定義された関数を呼び出すためにJNIを使​​用しようとしています。Javaプログラムを実行すると、1つの間違いが発生することもあれば、別の間違いが発生することもあるため、本当に奇妙です。どうぞ:

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

そして、これを呼び出すために使用するJavaコードは次のとおりです。

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 ライブラリを含める方法にあると思います。

あなたが私を助けてくれることを願っています。ありがとうございました

4

2 に答える 2

3

プログラムを cygwin ライブラリにリンクさせたい場合を除き、cygwin GCC を使用しないでください。必要な場合は、cygwin dll もパッケージに含める必要があります。

Windows上で動かしたい場合は、mingwコンパイラ(Cygwin用のパッケージもありますが、cygwinに依存しないバイナリを作成します)またはMSVCプロジェクトを使用してください。Java が cygwin に対応していない場合、Java は cygwin パスを理解できませんが、ネイティブ コードは理解します。それは本当に混乱するでしょう。必要であることがわかっていない限り、スクリプトには cygwin を使用しますが、コンパイラとして mingw-gcc を使用してバイナリを作成するか、Min Lin のスタジオ プロジェクトを使用します。

于 2013-04-10T11:59:51.113 に答える
1

私の推測では、gsl ライブラリがコンパイルされ、別のバージョンの cygwin にリンクされている可能性があります。また、main.c コードが現在のバージョンの cygwin でコンパイルされている場合、競合が発生します。これらを試すことができます:

  1. 現在の cygwin 環境を使用して gsl を再構築します。
  2. gsl のスタティック ライブラリへのリンク。
  3. msvc を使用すると、msvc で gsl をコンパイルできます。ビジュアル スタジオ ソリューションがあり、静的ライブラリまたは動的ライブラリを作成できます。
于 2013-04-10T09:51:14.503 に答える