我正在尝试JNI示例代码。
(您可以通过github获得以下所有源代码:https://github.com/pilhoon/jni-test)
public class Sample { public native int intMethod(int n); public native boolean booleanMethod(boolean bool); public native String stringMethod(String text); public native int intArrayMethod(int[] intArray); public static void main(String[] args) { System.loadLibrary("sample"); Sample sample = new Sample(); int square = sample.intMethod(5); boolean bool = sample.booleanMethod(true); String text = sample.stringMethod("JAVA"); int sum = sample.intArrayMethod(new int[]{1,1,2,3,5,8,13} ); System.out.println("intMethod: " + square); System.out.println("booleanMethod: " + bool); System.out.println("stringMethod: " + text); System.out.println("intArrayMethod: " + sum); } }
#include "sample.h" #include <string.h> #ifdef __cplusplus extern "C" { #endif JNIEXPORT jint JNICALL Java_Sample_intMethod (JNIEnv *env, jobject obj, jint num) { return num * num; } JNIEXPORT jboolean JNICALL Java_Sample_booleanMethod (JNIEnv *env, jobject obj, jboolean boolean) { return !boolean; } JNIEXPORT jstring JNICALL Java_Sample_stringMethod (JNIEnv *env, jobject obj, jstring string) { const char *str = (*env)->GetStringUTFChars(env, string, 0); char cap[128]; strcpy(cap, str); (*env)->ReleaseStringUTFChars(env, string, str); return (*env)->NewStringUTF(env, strupr(cap)); } JNIEXPORT jint JNICALL Java_Sample_intArrayMethod (JNIEnv *env, jobject obj, jintArray array) { int i, sum = 0; jsize len = (*env)->GetArrayLength(env, array); jint *body = (*env)->GetIntArrayElements(env, array, 0); for (i=0; iReleaseIntArrayElements(env, array, body, 0); return sum; } void main(){} #ifdef __cplusplus } #endif
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Sample */ #ifndef _Included_Sample #define _Included_Sample #ifdef __cplusplus extern "C" { #endif /* * Class: Sample * Method: intMethod * Signature: (I)I */ JNIEXPORT jint JNICALL Java_Sample_intMethod (JNIEnv *, jobject, jint); /* * Class: Sample * Method: booleanMethod * Signature: (Z)Z */ JNIEXPORT jboolean JNICALL Java_Sample_booleanMethod (JNIEnv *, jobject, jboolean); /* * Class: Sample * Method: stringMethod * Signature: (Ljava/lang/String;)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_Sample_stringMethod (JNIEnv *, jobject, jstring); /* * Class: Sample * Method: intArrayMethod * Signature: ([I)I */ JNIEXPORT jint JNICALL Java_Sample_intArrayMethod (JNIEnv *, jobject, jintArray); #ifdef __cplusplus } #endif #endif
我在CentOS6.3上用gcc编译了这些
prompt$ gcc -c -o sample.o -fPIC sample.c -I /usr/java/jdk1.7.0_07/include/ -I /usr/java/jdk1.7.0_07/include/linux/ prompt$ gcc -shared -o libsample.so sample.o
但是当我运行'java sample'时,出现了一个错误。
java: symbol lookup error: /home/ph/tmp/jni/libsample.so: undefined symbol: strupr
我该怎么解决这个?
Java似乎对JNI库使用其他库有问题。我现在也有同样的问题,我想用Glib制作一个JNI库。Java不想知道油嘴滑舌的函数,尽管所有的编译和链接都很好。
因此,如果您编写JNI库,您就不能从该代码中使用任何其他库!
编辑:将任何库静态链接到您的JNI库中。那应该管用!
strupr不是标准的ANSI C。如果您编写一个引用strupr的本机C应用程序,您将得到一个与您看到的类似的链接错误
$ gcc -o sample -fPIC Sample.c -I /xxx/include/ -I /xxx/include/linux/
Sample.c: In function âJava_Sample_stringMethodâ:
Sample.c:23: warning: passing argument 2 of â(*env)->NewStringUTFâ makes pointer from integer without a cast
Sample.c: In function âmainâ:
Sample.c:40: warning: passing argument 1 of âprintfâ makes pointer from integer without a cast
/tmp/cc6hPBKz.o: In function `Java_Sample_stringMethod':
Sample.c:(.text+0xaa): undefined reference to `strupr'
/tmp/cc6hPBKz.o: In function `main':
Sample.c:(.text+0x103): undefined reference to `strupr'
collect2: ld returned 1 exit status
解决方法是编写自己的strupr例程。
在包含stdio.h
和/或string.h
之后,是否尝试编译C文件?
问题内容: 我正在使用dlopen在运行时加载共享库 在该共享库中,我引用了另一个共享库“ SharedLibarary2.so”中定义的const char *。 可执行文件和两个库都是使用-rdynamic构建的。 但是使用dlopen时,我仍然收到运行时错误:“ / usr / lib / SharedLibarary1.so:未定义符号”,并指向损坏的const char *具有未定义符号
我试图加载一个. so文件(libInfExprParser.so)使用JNI。我没有这个共享对象的源代码。我得到以下错误: 线程“main”java中出现异常。lang.unsatifiedlinkerror:/home/tomcat/sahiti/ExprParser/libinfexparser。所以:/home/tomcat/sahiti/ExprParser/libinexprparse
问题内容: 我正在尝试使用一百万首歌曲数据集,为此,我不得不安装python表,numpy,cython,hdf5,numexpr等。 昨天我设法安装了所有需要的东西,并且在使用hdf5遇到了一些麻烦之后,我下载了预编译的二进制程序包,并将它们保存在我的/ bin文件夹和/ lib中的相应库中,然后测试了此python脚本: 而且工作正常,要明确我的工作方式是先运行脚本并开始安装所需的依赖项,但是
问题内容: 当我尝试在python中执行我的主文件时遇到问题(我在使用python 2.7的Ubuntu 12.04上)。我收到此错误: 目前scipy是使用Python软件包管理器安装的(请参阅我以前的文章:python:scipy安装在ubuntu上)。 谢谢。 问题答案: 您正在使用与用于编译scipy的Python解释器不同的Python解释器来运行代码。这通常发生在使用Unicode U
问题内容: 当我尝试在python中执行我的主文件时遇到问题(我在使用python 2.7的Ubuntu 12.04上)。我收到此错误: 目前scipy是通过Python软件包管理器安装的。 谢谢。 问题答案: 您正在使用与用于编译scipy的Python解释器不同的Python解释器来运行代码。这通常发生在使用Unicode UCS2支持编译的Python安装程序,运行针对使用UnicodeUC
我目前正在尝试将Lambda作为Zappa(Python3.6)发布。在AWS端部署应用程序/配置所有内容后,我运行以下命令在本地环境中测试应用程序, 并且得到了这个错误, /tmp/virtualenv_name/pymssql。cpython-36m-x86_64-linux-gnu。so:未定义符号:PyFPE_jbuf:ImportTerror 回溯(最后一次调用):lambda_hand