linux64位下jni调用c/c++动态链接库

[size=medium]搭配的开发环境:
操作系统:linux(64位)
开发环境:Eclipse(64位)
Jdk版本:jdk1.6.0_26 (64位)

首先需要查看一下操作系统和环境变量中设置的jdk是多少位的,可以使用下面的命令:

查看操作系统位数: file /bin/ls
[root@LVS1 ~]#  file /bin/ls  
/bin/ls: ELF 64-bit LSB executable, AMD x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped

查看环境变量中设置的jdk位数: java -version
[root@LVS1 ~]# java -version
java version "1.6.0_26"

Eclipse(64位)是从网站上下载的可以运行在64位操作系统上的开发工具。

第一步:新建java project工程名jnitest,在src下面建立HelloWorld.java
\

public class HelloWorld {
	public native void SayHello( );// 是java本地方法申明

	public HelloWorld() {
	}

	static {
			System.loadLibrary("helloworld");// 装入动态链接库,"helloworld"是要装入的动态链接库名称。
	}

}


第二步:在src下面建立测试类ToSay.java 
public class ToSay {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		System.out.println(System.getProperty("java.library.path"));
		System.out.println(System.getProperty("os.arch"));
		HelloWorld hello = new HelloWorld();
		hello.SayHello( );

	}
} 

第三步:生成c/c++文件
1.生成HelloWorld.class文件
javac HelloWorld.java

2.生成HelloWorld.h文件
javah -classpath . HelloWorld

3.在src下新建立一个libhelloworld.cpp文件,生成libhelloworld.so文件
g++ -I /usr/java/jdk1.6.0_26/include/linux/ -I /usr/java/jdk1.6.0_26/include/ -fPIC -shared -o libhelloworld.so HelloWorld.cpp 
HelloWorld.cpp 源码
#include "HelloWorld.h"

#include <stdio.h>



JNIEXPORT void JNICALL Java_HelloWorld_SayHello(JNIEnv * env, jobject arg)

{
    printf("  64 位====  HelloWorld !/n");


    return;

}


4.指定libhelloworld.so动态库所在的路径
export LD_LIBRARY_PATH=/usr/java/jdk1.6.0_26/jre/lib/amd64/server

#LD_LIBRARY_PATH这个环境变量指示动态连接器可以装载动态库的路径。
此步是设置将库文件所在路径加入LD_LIBRARY_PATH中去,如果不执行此步,在运行中就会出现异常: java.lang.UnsatisfiedLinkError: no XXX in java.library.path 

5.生成ToSay.class文件
javac -cp . ToSay.java

6.测试ToSay
java -cp . ToSay
[root@LVS1 src]# java -cp . ToSay
/usr/java/jdk1.6.0_26/jre/lib/amd64/server:/usr/java/jdk1.6.0_26/jre/lib/amd64:/usr/java/jdk1.6.0_26/jre/../lib/amd64:/usr/java/jdk1.6.0_26/jre/lib/amd64/server:/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
amd64
  64 位====  HelloWorld !/n



过程中如果出现
Exception in thread "main" java.lang.UnsatisfiedLinkError: /usr/java/jdk1.6.0_20/jre/lib/i386/libhelloworld.so: /usr/java/jdk1.6.0_20/jre/lib/i386/libhelloworld.so: wrong ELF class: ELFCLASS64 (Possible cause: architecture word width mismatch)
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1803)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1720)
	at java.lang.Runtime.loadLibrary0(Runtime.java:823)
	at java.lang.System.loadLibrary(System.java:1028)
	at HelloWorld.<clinit>(HelloWorld.java:9)
	at ToSay.main(ToSay.java:9)

是因为jdk位数的问题,重装了个64位的jdk就行了,可能是因为服务器是64位的,32位的jdk调用64位的文件出问题,同步一下就好了。

看一下so文件的"地址",是32位的还是64的即可,或者有没有依赖/lib64下的文件.
ldd /usr/java/jdk1.6.0_26/jre/lib/amd64/server/libhelloworld.so
过程中如果出现
Exception in thread "main" java.lang.UnsatisfiedLinkError: no helloworld in java.library.path
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1738)
	at java.lang.Runtime.loadLibrary0(Runtime.java:823)
	at java.lang.System.loadLibrary(System.java:1028)
	at HelloWorld.<clinit>(HelloWorld.java:9)
	at ToSay.main(ToSay.java:9)

是因为动态加载库的路径问题,可以指定动态加载库的路径 
export LD_LIBRARY_PATH=/usr/java/jdk1.6.0_26/jre/lib/amd64/server
[/size]

你可能感兴趣的:(linux)