2016-07-21 97 views
0

我正在處理一些本地代碼以將RPI感應帽與我的java東西進行接口,而且我無法讓我的本機意味着。我已經在java中編寫了存根,編譯它然後使用javah來提取頭文件。我創建了C中的方法來將一個簡單的char數組轉換爲一個字符串來返回。我似乎無法得到它編譯。 的Java:無法編譯JNI C不兼容的指針類型

/** 
* 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(); 

} 

頭文件

/* 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文件:

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

我使用下面的命令編譯它:

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

你能提供編譯器輸出嗎? – Sergio

回答

1

你可以用」 t do

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

應該

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

甚至

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

還你不應該free(done)。此內存未分配到malloc(),因此釋放會導致未定義的行爲。

+0

幹得好極了。 :D – MAWood

+0

*你不能這樣做......'NewStringUTF(env,&done);'*不正確,'array'和'&array'都是正確的,它們都計算到'array'的第一個元素的地址。編寫一些能夠發出'array'和'&array'結果的代碼,例如'printf(「%p \ n%p \ n」,done,&done);'',這兩個地址是相同的。在這個問題中發佈的代碼是'free(done)'行。 –

+0

@AndrewHenle無論指針指向相同的內存位置,它們都有完全不同的類型,'done'是'char *','&done'是'char(*)[]'。函數有下一個原型'jstring NewStringUTF(JNIEnv * env,const char * bytes);'so'&done'是不可接受的參數,編譯器告訴它。 – Sergio

1

我看到的第一個問題是:聲明本地數組變量並在它們上使用free()。可以使用malloc()/ free()或者在本地聲明你的數組,但不要混合使用兩者。