1)首先我已经通过了网络上关于讲解JNI的程序,也就是说使用JNI的过程和路径的设置不会有什么问题
2)我自己编写的程序:
//opentest.java文件,欲生成opentest.h文件
public class opentest
{
    static
    {
        System.loadLibrary("openwq");
    }
    public native static int optest();
}//opentest.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class opentest */
                                                                                
#ifndef _Included_opentest
#define _Included_opentest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     opentest
 * Method:    optest
 * Signature: ()I
 */
JNIEXPORT jint JNICALL Java_opentest_optest
  (JNIEnv *, jclass);
                                                                                
#ifdef __cplusplus
}
#endif
#endif//openwq.c
#include<opentest.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/stat.h>
int pttyfd;
int optest()
{
    pttyfd = open("/dev/ttyS0", O_RDWR | O_NOCTTY |O_NDELAY);
    return pttyfd;
}我将openwq.c用gcc -I/usr/java/j2sdk1.4.2_06/include -I/usr/java/j2sdk1.4.2_06/include/linux -fPIC -c openwq.c编译成openwq.o文件
              用gcc -shared -W1,-soname,libopenwq.so.1 -o libopenwq.so.1.0 openwq.o编译成libopenwq.so//openmain.java
public class openmain
{
    public static void main(String[] args)
    {
        int i;
        opentest test=new opentest();
        i=test.optest();
        System.out.println(i);
        }
}javac openmain.java通过
java openmain时:
Exception in thread "main" java.lang.UnsatisfiedLinkError: optest
        at opentest.optest(Native Method)
        at openmain.main(openmain.java:7)
高手们能解答么,俯身下谢,一躬到底!

解决方案 »

  1.   

    你必须设置LD_LIBRARY_PATH,用以下方法就可以
    export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
    更简单些(如果你只在当前目录调用JNI)
    export LD_LIBRARY_PATH=.
      

  2.   

    我晕:没看清,有问题:
    你的openwq.c根本没有JNI optest()的实现,改为
    JNIEXPORT jint JNICALL Java_opentest_optest (JNIEnv *env, jclass obj)
    {
       pttyfd = open("/dev/ttyS0", O_RDWR | O_NOCTTY |O_NDELAY);
        return (jint)pttyfd;
    }
      

  3.   

    我服了,问题迎刃而解,关键是函数的参数,我以前的是(JNIEnv *,jclass),编译出错,现在好了!顺便想问一句,您是做什么的啊?(该问题10分)
      

  4.   

    我是一名程序员,只是用了多年的C/C++.最近才用JAVA的
      

  5.   

    又有新问题:
    我的arraywq.h为:
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class arraywq */
                                                                                                                                                  
    #ifndef _Included_arraywq
    #define _Included_arraywq
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     arraywq
     * Method:    showarray
     * Signature: (I[B)I
     */
    JNIEXPORT jint JNICALL Java_arraywq_showarray
      (JNIEnv *, jclass, jint, jbyteArray);
                                                                                                                                                  
    #ifdef __cplusplus
    }
    #endif
    #endif
    我的arrayso.c 为:
    #include"arraywq.h"
    #include<stdio.h>
    void add_0(char * c,int len)
    {
        int i;
        for(i=0;i<len;i++) *c++;
        *c++='\0';
    }
    JNIEXPORT jint JNICALL Java_arraywq_showarray
      (JNIEnv *env, jclass obj, jint len, jbyteArray jarr)
    {
        jbyte *arr = env->GetByteArrayElements(jarr, 0);
        char * c=(char *)arr;
        add_0(c,len);
        printf("%s\n",c);
        return len;
    }
    用gcc -I/usr/java/j2sdk1.4.2_06/include -I/usr/java/j2sdk1.4.2_06/include/linux -fPIC -c arrayso.c编译后,出现:
    arrayso.c: In function `Java_arraywq_showarray':
    arrayso.c:12: error: request for member `GetByteArrayElements' in something not a structure or union
    并且每次关闭arrayso.c文件后再打开就说我的"交换文件"已经存在,要我退出或什么的,请指教!
    (我是吉林大学的学生,我的QQ是40862858,希望能交你做朋友,也请以后多多关照)
      

  6.   

    你的例子是否是书上/网上抄来的
    jbyte *arr = env->GetByteArrayElements(jarr, 0);
    只有C++是才用
    在C中的写法应该是
    jbyte * arr = (*env)->GetByteArrayElements(env,jarr, NULL);
    ---------------------------------------------------------------
    在C的定义中,env是一个两级指针,而在C++的定义中,env是个一级指针
    -------------------------------------------------------------
    我第一次用它时,也犯过同样的错,JNI的资料很少,连SUN网站上有些资料也是过时的,不到万不得意,少用为妙
    -----------------------------------------------------------
    我不用QQ上,有问题可发CSDN短信给我
      

  7.   

    例子是网上的,按照你的方法已经通过.我用JNI是因为以前我在LINUX下用C编了一个通讯程序,学了JAVA后觉得有一些WEB功能还是用JAVA实现简单.如果不用JNI我还有什么办法吗.
      

  8.   

    java是没有指针的,返回数组是可行的,以下是我写的例子
    (*******注意,我是用C++写的,请一定用.cpp做后缀*********)
    //test.java
    public class test {
      static {
          System.loadLibrary("dlltest");
      }
      public native static int ctest();
      public native static byte[] newarrtest();
     
      public static void main(String args[]) {
           System.out.println("I'm in java");
           int i=ctest();
           System.out.println("I get a return of int:"+i);
           byte [] bt=newarrtest();
           System.out.println("I get a return of array:");
           for(i=0;i<bt.length;i++)
             System.out.println(bt[i]);
       }
    }
    ///dlltest.cpp
    #include "test.h"
    #include <stdio.h>
    JNIEXPORT jint JNICALL Java_test_ctest(JNIEnv *, jclass)
    {
      printf("Now I'm in C++\n");
      return (jint)100; 
    }
    JNIEXPORT jbyteArray JNICALL Java_test_newarrtest(JNIEnv *env, jclass)
    {
    jbyteArray bts=env->NewByteArray(10);  //new byte[]
    jbyte buff[10];
    for(int i=0;i<10;i++)
      buff[i]=i+100;                       
    env->SetByteArrayRegion(bts,0,10,buff);  // set byte[] values
    return bts;
    }
      

  9.   

    在*.C文件中怎么实现啊,我的.SO文件是用C编写的,我不太懂C++(辛苦你了,再加50分)
    谢谢!
      

  10.   

    ////jni 从C++ ==> C
    ///1. C 必须定义参数名 (JNIEnv *env, jclass cl)
    ///2. C 的变量只能定义在函数的头上
    ///3. JNI中的C函数中env为二级指针,且参数与C++不同#include "test.h"
    #include <stdio.h>
    JNIEXPORT jint JNICALL Java_test_ctest(JNIEnv *env, jclass cl)
    {
      printf("Now I'm in C++\n");
      return (jint)100; 
    }
    JNIEXPORT jbyteArray JNICALL Java_test_newarrtest(JNIEnv *env, jclass cl)
    {
    jbyteArray bts;
    jbyte buff[10];
    int i;

    bts=(*env)->NewByteArray(env,10);  //new byte[]
    for(i=0;i<10;i++)
      buff[i]=i+100;                       
    (*env)->SetByteArrayRegion(env,bts,0,10,buff);  // set byte[] values
    return bts;
    }