Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access C constants (header) from JNI (Java Native Interface)

how do I access constants defined in the C header file from Java side (through JNI)?

I have a C library with this header file c_header.h:

// I'll try to get these values in java
#define PBYTES 64
#define SBYTES 128
#define SGBYTES 128

Then I have this java code libbind_jni.java:

package libbind;

public class libbind_jni {
static{
    try {
        System.load("libbind_jni.so");
    } catch (UnsatisfiedLinkError e) {
        System.err.println("Native code library failed to load.\n" + e);
        System.exit(1);
    }
}

public static native String[] pubm(String seed);

Then running javah at libbind_jni.java I generate JNI header file jni_header.h:

#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     libbind_libbind_jni
 * Method:    pubm
 * Signature: (Ljava/lang/String;)[Ljava/lang/String;
 */
JNIEXPORT jobjectArray JNICALL Java_lib_f_1jni_pubm
  (JNIEnv *, jclass, jstring);

Then I write a little C code for JNI library jni_source.c:

#include "jni_header.h"
#include "c_header.h"
#include <stdlib.h>

JNIEXPORT jobjectArray JNICALL Java_libbind_libbind_1jni_pubm
  (JNIEnv *env, jclass cls, jstring jniSeed){
    unsigned char vk[PBYTES];
    unsigned char sk[SBYTES];
    <whatever...>
}

-- Here goes compiling of C library for java -- libbind.so

And the JAVA source j_source.java:

import libbind.libbind_jni;

public class test {

    /* trying to access constants from library (libbind.so) */
    System.out.println(libbind_jni.PBYTES);
    System.out.println(libbind_jni.SBYTES);
    System.out.println(libbind_jni.SGBYTES);

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


$ javac test.java

test.java:5: cannot find symbol
symbol  : variable PBYTES
location: class libbind.libbind_jni
    System.out.println(libbind_jni.PBYTES);

So the question is: How do I access these definitions/constants in C header file from Java?

Thanks.

like image 534
Edgaras Lukoševičius Avatar asked May 02 '13 09:05

Edgaras Lukoševičius


1 Answers

Simple answer is that you can't. You'll have to define the same values in Java.

public static final int PBYTES = 64;
public static final int SBYTES = 128;
public static final int SGBYTES = 128;

Or you can define some native methods that return these values. But the macros as such cannot be accessed from Java.

public static native int PBYTES();
public static native int SBYTES();
public static native int SGBYTES();
like image 157
maba Avatar answered Sep 29 '22 03:09

maba