MAWood
MAWood

Reputation: 99

Can't compile JNI C incompatible pointer type

I'm working on some native code to interface the RPI sense hat with my java stuff and I can't get my native to imply. I have written the stubs in java, compiled it then used javah to extract a header file. I created the methods in C to turn a simple char array into a string for returning. I can't seem to get it to compile. Java:

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

}

Header file:

/* 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 file:

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

I'm compiling it using the following command:

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

Upvotes: 0

Views: 802

Answers (2)

candidus
candidus

Reputation: 129

The first problem I see: You declare local array variables and use free() on them. Either use malloc()/free() or declare your array locally, but don't mix both.

Upvotes: 1

Sergio
Sergio

Reputation: 8209

You can't do

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

it should be

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

or even

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

also you shouldn't free(done). This memory was not allocated with malloc() so freeing leads to undefined behavior.

Upvotes: 1

Related Questions