2016-07-21 11 views
0

Ich arbeite an etwas nativem Code, um den RPI-Sinneshut mit meinen Java-Zeug zu verbinden, und ich kann meinen Einheimischen nicht dazu bringen, zu implizieren. Ich habe die Stubs in Java geschrieben, kompiliert und dann mit javah eine Header-Datei extrahiert. Ich habe die Methoden in C erstellt, um ein einfaches char-Array in eine Zeichenfolge umzuwandeln. Ich kann es anscheinend nicht zum Kompilieren bringen. Java:Kompilieren von JNI C inkompatiblen Zeigertyp

/** 
* NativeTest - PACKAGE_NAME 
* Created by matthew on 21/07/16. 
*/ 
class SenseHat 
{ 
    static { 
     System.loadLibrary("SenseHat"); 
    } 

    public native String getTemperature(); 
    public native String getHumidity(); 
    public native String getOrientation(); 

} 

Headerdatei:

/* DO NOT EDIT THIS FILE - it is machine generated */ 
#include <jni.h> 
/* Header for class SenseHat */ 

#ifndef _Included_SenseHat 
#define _Included_SenseHat 
#ifdef __cplusplus 
extern "C" { 
#endif 
/* 
* Class:  SenseHat 
* Method: getTemperature 
* Signature:()Ljava/lang/String; 
*/ 
JNIEXPORT jstring JNICALL Java_SenseHat_getTemperature 
    (JNIEnv *, jobject); 

/* 
* Class:  SenseHat 
* Method: getHumidity 
* Signature:()Ljava/lang/String; 
*/ 
JNIEXPORT jstring JNICALL Java_SenseHat_getHumidity 
    (JNIEnv *, jobject); 

/* 
* Class:  SenseHat 
* Method: getOrientation 
* Signature:()Ljava/lang/String; 
*/ 
JNIEXPORT jstring JNICALL Java_SenseHat_getOrientation 
    (JNIEnv *, jobject); 

#ifdef __cplusplus 
} 
#endif 
#endif 

C-Datei:

#include <jni.h> 
#include <stdio.h> 
#include "SenseHat.h" 

JNIEXPORT jstring JNICALL Java_SenseHat_getTemperature(JNIEnv *env, jobject thisObj) { 
    char done[] = "temperature"; 
    jstring answer; 
    /* Make a new String based on done, then free done. */ 
    answer = (*env)->NewStringUTF(env,&done); 
    free(done); 
    return answer; 

} 

JNIEXPORT jstring JNICALL Java_SenseHat_getHumidity(JNIEnv *env, jobject thisObj) { 
    char done[9] = "humidity"; 
    jstring answer; 
    /* Make a new String based on done, then free done. */ 
    answer = (*env)->NewStringUTF(env,&done); 
    free(done); 
    return answer; 

} 

JNIEXPORT jstring JNICALL Java_SenseHat_getOrientation(JNIEnv *env, jobject thisObj) { 
    char done[12] = "orientation"; 
    jstring answer; 
    /* Make a new String based on done, then free done. */ 
    answer = (*env)->NewStringUTF(env,&done); 
    free(done); 
    return answer; 
} 

Ich Kompilieren Sie den folgenden Befehl:

gcc -I /usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/include/ -I /usr/lib/jvm/jdk-8-oracle-arm32-vfp-hflt/include/linux/ -shared -o libSenseHat.so SenseHat.c 
+1

Könnten Sie Compiler-Ausgabe bereitstellen? – Sergio

Antwort

1

Sie können‘ t tun

char done[] = "temperature"; 
    /* ... */ 
    answer = (*env)->NewStringUTF(env,&done); 
           /* --^-- & is redundant */ 

sollte es

char done[] = "temperature"; 
    /* ... */ 
    answer = (*env)->NewStringUTF(env,done); 

oder sogar

answer = (*env)->NewStringUTF(env,"temperature"); 

sein auch Sie sollten nicht free(done). Dieser Speicher wurde nicht mit malloc() zugewiesen, sodass Leads nicht definiert werden.

+0

Prost das hat super funktioniert. : D – MAWood

+0

* Sie können nicht tun ... 'NewStringUTF (env, &done);' * ist falsch. 'Array' und' & Array' sind beide korrekt und sie beide bewerten die Adresse des ersten Elements von 'array'. Versuchen Schreiben von Code, der das Ergebnis von 'array' und' & array' ausgibt, wie zum Beispiel 'printf ("% p \ n% p \ n ", erledigt, & fertig);'. Die beiden Adressen werden identisch sein Der Code, der in der Frage geschrieben wird, ist die Zeile "free (done);" –

+0

@AndrewHenle Unabhängig davon, dass Zeiger auf denselben Speicherort verweisen, haben sie absolut unterschiedliche und inkompatible Typen. 'done' ist' char * 'und' & done' ist 'char (*) []'. Die Funktion hat den nächsten Prototyp 'jstring NewStringUTF (JNIEnv * env, const char * bytes);' so '& done' ist ein inakzeptables Argument und der Compiler erzählt davon. – Sergio

1

Das erste Problem, das ich sehe: Sie deklarieren lokale Array-Variablen und verwenden Sie free() auf ihnen. Verwenden Sie entweder malloc()/free() oder deklarieren Sie Ihr Array lokal, aber mischen Sie beides nicht.