2013-05-02 58 views
4

如何从Java端(通过JNI)访问C头文件中定义的常量?从JNI(Java Native Interface)访问C常量(头文件)

我有一个C库与该头文件c_header.h:

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

然后,我有此java代码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); 

然后运行JAVAH在libbind_jni.java我生成JNI头文件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); 

然后我为JNI库jni_source.c编写一个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...> 
} 

- 在这里不用对Java编译C库 - libbind.so

和Java源代码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); 

所以现在的问题是:如何访问这些定义/常量来自Java的C头文件?

谢谢。

回答

2

简单的答案是,你不能。您必须在Java中定义相同的值。

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

或者你可以定义一些返回这些值的本地方法。但是这样的宏不能从Java访问。

public static native int PBYTES(); 
public static native int SBYTES(); 
public static native int SGBYTES(); 
+0

另一种方式呢 - 从C++访问Java常量?有没有办法避免在C++代码中定义相同的值? – biggvsdiccvs 2016-12-16 03:36:50

+0

@biggvsdiccvs可以做到,因为Java常量只是普通的类成员。尽管如此,你需要做一些重要的JNI编码。 – maba 2016-12-16 09:03:28

+0

我还没有实际做过任何JNI编码(但是有相当多的纯Java编码)。如果你能指向正确的方向,我会非常感激。我正在尝试为几个摄像头驱动程序编写Java包装器。 C++ API针对不同的参数(例如曝光和快门模式等)提供了一系列setter方法,并且我认为使用一个键值对的setter可能工作较少,但是键和一些值应该定义为常量。这实际上会减少工作吗? – biggvsdiccvs 2016-12-16 12:25:37