我在编写好到JNI程序在但文件里进行本地方法到声明和加载 然后在main函数内调用一切正常,但是我把本地方法到声明和库的加载放到一个新到文件里用新的类封装后,在主文件里调用就会出现如下异常信息:
Exception in thread "main" java.lang.UnsatisfiedLinkError: com.serialport.jni.SerialJNI.OpenDev(Ljava/lang/String;)I
at com.serialport.jni.SerialJNI.OpenDev(Native Method)
at com.serialport.jni.SerialJNI.<init>(SerialJNI.java:22)
at Serial.main(Serial.java:11)主程序:import com.serialport.jni.SerialJNI;public class Serial { public static void main(String[] args) throws Exception{
int fd;
int nread;
String wb = "abcdefghijklmnopqrstuvwxyz111111111111111111111";
String buff = new String();
String nBuff = new String();
SerialJNI serialPort = new SerialJNI("/dev/ttyUSB0", 9600, 8, 1, 'N');
fd = serialPort.getSerialPort();
serialPort.write(fd, wb, wb.length());
        while(true)
{
buff = serialPort.read(fd, 512);
nread = buff.length();
if(nread > 0)
{
System.out.print(buff);
nBuff = nBuff.concat(buff);
if(nBuff.length() >= wb.length())
{
//nBuff(wb.length()+1) = '\0';
System.out.println();
break;
}
}
}
System.out.println("read:"+nBuff);
System.out.println("finish!");
serialPort.close_port(fd);
        }
}
JNI调用类package com.serialport.jni;public class SerialJNI{

public native int OpenDev(String Dev);
public native void set_speed(int fd, int speed);
public native int set_Parity(int fd, int databits, int stopbits, int parity);
public native void write(int fd, String wb, int len);
public native String read(int fd, int len);
public native void close_port(int fd);

static{
System.loadLibrary("Serial");
} private int fd;

public SerialJNI(String Dev, int speed, int databits, int stopbits, int parity)
{
fd = OpenDev(Dev);
set_speed(fd, speed);
if(set_Parity(fd, 8, 1, 'N') == -1)
{
System.out.println("Set Parity Error");
return;
}
}

public int getSerialPort()
{
return fd;
}
}
把两个文件合并起来运行正常输出wb中到字符串,求高人指点,我后来在里面添加了各种抛出异常到语句还是不行

解决方案 »

  1.   

    jni的问题不是都解决了吗?怎么又出问题!我对这方面用得不多,帮你顶
      

  2.   

    放在一个文件下面是没问题了。。我想把JNI部分跟主程序部分分开到两个文件里,结果就一直报那个异常,网上到办法我都试遍了。。郁闷,我把其他文件也贴一下吧#include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <termios.h>
    #include <errno.h>
    #include <string.h>
    #include <jni.h>
    #include "SerialJNI.h"int speed_arr[]={B38400, B19200, B9600, B4800, B2400, B1200, B300,
    B38400, B19200, B9600, B4800, B2400, B1200, B300,};
    int name_arr[]={38400, 19200, 9600, 4800, 2400, 1200, 300, 38400,
    19200, 9600, 4800, 2400, 1200, 300,};JNIEXPORT jint JNICALL Java_SerialJNI_OpenDev
      (JNIEnv *env, jobject obj, jstring Dev)
    {
    const char *Dev_utf = (*env)->GetStringUTFChars(env, Dev, JNI_FALSE);
    int fd = open(Dev_utf, O_RDWR|O_NOCTTY);
    (*env)->ReleaseStringUTFChars(env, Dev, Dev_utf);
    if(-1 == fd)
    {
    perror("Can't Open Serial Port\n");
    return -1;
    }
    else
    {
    printf("Serial Open\n");
    return fd;
    }
    }JNIEXPORT void JNICALL Java_SerialJNI_set_1speed
      (JNIEnv *env, jobject obj, jint fd, jint speed)
    {
    int i;
    int status;
    struct termios Opt;
    tcgetattr(fd, &Opt);
    for(i=0; i<sizeof(speed_arr)/sizeof(int); i++)
    {
    if(speed == name_arr[i])
    {
    tcflush(fd, TCIOFLUSH);
    cfsetispeed(&Opt, speed_arr[i]);
    cfsetospeed(&Opt, speed_arr[i]);
    status = tcsetattr(fd, TCSANOW, &Opt);
    if(status != 0)
    perror("tcsetattr fd1\n");
    return ;
    }
    tcflush(fd, TCIOFLUSH);
    }
    }JNIEXPORT jint JNICALL Java_SerialJNI_set_1Parity
      (JNIEnv *env, jobject obj, jint fd, jint databits, jint stopbits, jint parity)
    {
    struct termios opt;
    if(tcgetattr(fd, &opt) != 0)
    {
    perror("SetupSerial 1\n");
    return -1;
    }
    opt.c_cflag &= ~CSIZE;
    opt.c_lflag &= ~(ICANON|ECHO|ECHOE|ISIG);
    opt.c_oflag &= ~OPOST; switch(databits)
    {
    case 7: opt.c_cflag |= CS7; break;
    case 8: opt.c_cflag |= CS8; break;
    default: fprintf(stderr, "Unsupported data size\n"); 
     return -1;
    }
    switch(parity)
    {
    case 'n': 
    case 'N': opt.c_cflag &= ~PARENB;
      opt.c_iflag &= ~INPCK;
      break;
    case 'o':
    case 'O': opt.c_cflag |= (PARODD|PARENB);
      opt.c_iflag |= INPCK;
      break;
    case 'e':
    case 'E': opt.c_cflag |= PARENB;
      opt.c_cflag &= ~PARODD;
      opt.c_iflag |= INPCK;
      break;
    case 's':
    case 'S': opt.c_cflag &= ~PARENB;
      opt.c_cflag &= ~CSTOPB;
      break;
    default: fprintf(stderr, "Unsupported parity\n");
     return -1;
      
    }
    switch(stopbits)
    {
    case 1: opt.c_cflag &= ~CSTOPB; 
                            break; 
    case 2: opt.c_cflag |= CSTOPB;
    break;
    default: fprintf(stderr,"Unsupported stop bits\n"); 
     return -1; 
    } if (parity != 'n')  opt.c_iflag |= INPCK;
    // tcflush(fd,TCIFLUSH);
    opt.c_cc[VTIME] = 150; /* 设置超时 15 seconds*/  
    opt.c_cc[VMIN] = 0; 
    tcflush(fd, TCIFLUSH);
    if (tcsetattr(fd,TCSANOW,&opt) != 0)  
    {
    perror("SetupSerial 3\n");  
    return -1; 
    }
     return 0; 
    }JNIEXPORT void JNICALL Java_SerialJNI_write
      (JNIEnv *env, jobject obj, jint fd, jstring buff, jint len)
    {
    const char *buff_utf = (*env)->GetStringUTFChars(env, buff, JNI_FALSE);
    if(write(fd, buff_utf, len)>0)
    {
    printf("write success!\nwrite:%s\n", buff_utf);
    }
    else
    {
    perror("write failed!\n");
    }
    (*env)->ReleaseStringUTFChars(env, buff, buff_utf);
    printf("write finish!\n");
    return;
    }JNIEXPORT jstring JNICALL Java_SerialJNI_read
      (JNIEnv *env, jobject obj, jint fd, jint len)
    {
    int nread=0;
    char tempBuff[len];
    jstring jstr;
    bzero(tempBuff, sizeof(tempBuff));
    while((nread = read(fd, tempBuff, len))>0)
    {
    tempBuff[nread+1] = '\0';
    jstr = (*env)->NewStringUTF(env, tempBuff);
    return jstr;
    }
    }JNIEXPORT void JNICALL Java_SerialJNI_close_1port
      (JNIEnv *env, jobject obj, jint fd)
    {
    if(close(fd))
    {
    perror("close failed!\n");
    }
    else
    {
    printf("close success!\n");
    }
    }头文件/* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class SerialJNI */#ifndef _Included_SerialJNI
    #define _Included_SerialJNI
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     SerialJNI
     * Method:    OpenDev
     * Signature: (Ljava/lang/String;)I
     */
    JNIEXPORT jint JNICALL Java_SerialJNI_OpenDev
      (JNIEnv *, jobject, jstring);/*
     * Class:     SerialJNI
     * Method:    set_speed
     * Signature: (II)V
     */
    JNIEXPORT void JNICALL Java_SerialJNI_set_1speed
      (JNIEnv *, jobject, jint, jint);/*
     * Class:     SerialJNI
     * Method:    set_Parity
     * Signature: (IIII)I
     */
    JNIEXPORT jint JNICALL Java_SerialJNI_set_1Parity
      (JNIEnv *, jobject, jint, jint, jint, jint);/*
     * Class:     SerialJNI
     * Method:    write
     * Signature: (ILjava/lang/String;I)V
     */
    JNIEXPORT void JNICALL Java_SerialJNI_write
      (JNIEnv *, jobject, jint, jstring, jint);/*
     * Class:     SerialJNI
     * Method:    read
     * Signature: (II)Ljava/lang/String;
     */
    JNIEXPORT jstring JNICALL Java_SerialJNI_read
      (JNIEnv *, jobject, jint, jint);/*
     * Class:     SerialJNI
     * Method:    close_port
     * Signature: (I)V
     */
    JNIEXPORT void JNICALL Java_SerialJNI_close_1port
      (JNIEnv *, jobject, jint);#ifdef __cplusplus
    }
    #endif
    #endif还有顶楼贴的代码里把库名改成了SerialJNI,编译生成.so文件用的命令是:
    cc -I/home/administrator/java/jdk1.6.0_26/include -I/home/administrator/java/jdk1.6.0_26/include/linux -fPIC -shared -o libSerialJNI.so SerialJNI.c
    运行程序用的命令是:
    java -Djava.library.path='./com/serialport/jni/' Serial
    运行之后出现顶楼异常,继续求帮助,我在网上继续看看吧
      

  3.   

    好吧 我承认我2了,最近整这玩意儿弄到人有些憔悴,竟然犯这种低级错误,只是单纯到把文件拆分,路径全换了,结果.h文件没有按照新路径编译,导致生成到函数声明中有关路径到错误,导致.java文件找不到.c文件中对函数的实现,哎竟然就这么点问题害我纠结这么久。。好了linux下的JNI串口通信已经差不多了,下面往android上移植不知到又会有多少问题,结贴,散分,感谢瞎扯蛋同学的关注
      

  4.   

    貌似SerialJNI类要放在头文件指定的java包内。如:JNIEXPORT jint JNICALL Java_包名_类名_方法名。JNIEXPORT jint JNICALL Java_SerialJNI_OpenDev(JNIEnv *, jobject, jstring);这个应该是java中的默认包中的SerialJNI类中的OpenDev方法。
    改成下面的试试。JNIEXPORT jint JNICALL Java_com_serialport_jni
    _SerialJNI_OpenDev(JNIEnv *, jobject, jstring);
      

  5.   

    原来是做android,我最近也刚看这东西,或许有东西可以探讨!感觉android开发还是不难,java基础好的,上手会很快!
      

  6.   

    问题就是我JAVA才学了一个月,以前只有C/C++和MFC的基础,JAVA看的是孙鑫老师到那套视频,现在就是缺少实践,我会继续努力的