当前位置: 首页 > 知识库问答 >
问题:

jni未定义符号错误

南门意蕴
2023-03-14

我正在尝试JNI示例代码。
(您可以通过github获得以下所有源代码:https://github.com/pilhoon/jni-test)

  • sample.java
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);
  }
}
  • sample.c
#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

  • 采样.h
/* 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

我该怎么解决这个?

共有3个答案

臧令
2023-03-14

Java似乎对JNI库使用其他库有问题。我现在也有同样的问题,我想用Glib制作一个JNI库。Java不想知道油嘴滑舌的函数,尽管所有的编译和链接都很好。

因此,如果您编写JNI库,您就不能从该代码中使用任何其他库!

编辑:将任何库静态链接到您的JNI库中。那应该管用!

卓学智
2023-03-14

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例程。

顾学真
2023-03-14

在包含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