Search code examples
javactypesjava-native-interface

JNI not recognising jni primitive types e.g. string


I have made a make file for the C headers and this works fine but says that there is a syntax error with the JNICALL and JNIEnv but I have figured out that it is because of the type in the header file.

Image of the failure

The code in the picture is here:

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

#ifndef _Included_GameLogic
#define _Included_GameLogic
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     GameLogic
 * Method:    hello
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_GameLogic_hello
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

When I try to run the project I get the error:

Exception in thread "main" java.lang.UnsatisfiedLinkError: GameLogic.hello()Ljava/lang/String;
    at GameLogic.hello(Native Method)
    at GameLogic.<init>(GameLogic.java:7)
    at GameLogic.main(GameLogic.java:11)

The C file:

#import <jni.h>
#import <stdio.h>
#include "GameLogic.h"

JNIEXPORT jstring JNICALL Java_GameLogic_hello (JNIEnv * env, jobject thisObj) {
    return (*env)->NewStringUTF(env, "Sup");
}

Generic make file:

# Define a variable for classpath
CLASS_PATH = ../

# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)

all : libGameLogic.jnilib

# $@ matches the target, $< matches the first dependancy
libGameLogic.jnilib : GameLogic.o
    gcc -dynamiclib -framework JavaVM -o $@ $<

# $@ matches the target, $< matches the first dependancy
GameLogic.o : GameLogic.c GameLogic.h
    gcc -I/System/Library/Frameworks/JavaVM.framework/Headers -framework JavaVM -c $< -o $@

# $* matches the target filename without the extension
GameLogic.h : GameLogic.class
    javah -classpath $(CLASS_PATH) $*

clean :
    rm GameLogic.h GameLogic.o libGameLogic.jnilib

GameLogic:

public class GameLogic {

    public native String hello ();

    public GameLogic  () {
        System.out.println(hello());
    }

    public static void main (String[] args) {
        new GameLogic ();
    }

}

Solution

  • Try to compile using:

    gcc -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin/" -dynamiclib -o libGameLogic.jnilib GameLogic.c
    

    Then in your class file you need to add:

    static {
        // GameLogic.dll (Windows) or libGameLogic.so (Unixes) or libGameLogic.jnilib (Mac)
        System.loadLibrary("GameLogic");
    }
    

    And finally you launch your class as next (assuming that your file .class and your lib libGameLogic.jnilib are in the current directory):

    java -Djava.library.path=. GameLogic