为什么写这个呢,因为以前考试时考过静态链接库和动态链接库区别,我不清楚,这两天google了一下,从网上,园子里学到了一些这方面的知识,后来又发现它们也可以被其他语言调用,对于机器来说,啥语言写的代码到最后都是一样的,在二进制这一层都是相同的了,今天特用Java 按照网上例子小试了一下,折腾了我一个下午,粗心呀,还有身为小菜啥都不懂复制粘贴一大堆bug的无奈,记录一下,以后可能会用到。
我也写个最简单的。首先java代码:
public class java_dll{ static { System.loadLibrary("hello_dll"); } public native void printHelloWorld(int number); public static void main(String[] args){ java_dll test=new java_dll(); test.printHelloWorld(25); }}
实际上这个文件可以拆为2个文件,把main独立出去,里面只是一个测试代码。
javac java_dll.java
javah java_dll
编译一下,生成头文件,接下来重点来了
/* DO NOT EDIT THIS FILE - it is machine generated */ #include "jni.h" /* Header for class java_dll */ #ifndef _Included_java_dll #define _Included_java_dll #ifdef __cplusplus extern "C" { #endif /* * Class: java_dll * Method: printHelloWorld * Signature: (I)V */ JNIEXPORT void JNICALL Java_java_1dll_printHelloWorld (JNIEnv *, jobject, jint); #ifdef __cplusplus } #endif #endif
这是生成的头文件,不过我把<jni.h>改成了"jni.h',为什么呢?因为<>编译时,gcc回去它的include目录找,我不想把这个Java ,jdk/include目录下的文件拷到gcc目录,所以我直接把jni.h拷出来放到当前目录下。打开jni.h发现里面包含了
/* jni_md.h contains the machine-dependent typedefs for jbyte, jint
and jlong */
#include "jni_md.h"
这个文件在jdk/include/win32/目录下,也把它拷出来,楼主看jni_md.h文件内容也不多,直接把它拷出来覆盖了上面写的#include这一行。
好了,到了写c程序实现这个dll
#include <stdio.h> #include "java_dll.h" JNIEXPORT void JNICALL Java_java_1dll_printHelloWorld (JNIEnv * env, jobject obj, jint number){ printf("hello,world! you input number is %d",number); }
很简单,只是把java_dll.h里面那个函数用c语言实现就行了。
编译成dll,上面这个文件名字为hello.c,如果用gcc -shared hello.c -o hello_dll.dll,结果运行java java_dll的时候会出现
网上baidu,google了一下,最后发现这个博客说的比较好http://dikar.iteye.com/blog/382701
没有看错,下面那个huals发言就是我,这就是楼主小菜悲剧的开始,楼主用的是第一种方法
编译后还是一直报这个错误,楼主恼火了,搞这个已经搞了快3个小时了,还是报错,楼主深深体会到作为码农屌丝的无奈。
最后,你懂得
gcc -Wl,--kill-at -shared -o hello_dll.dll hello.c
java java_dll
终于ok了,错误就是在于楼主把Wl输成WI,搞了快一个小时,还以为错误出在别处,网上一搜各种答案,各种奇葩。作为小菜,伤不起呀,有木有啊有木有。
楼主就先写到此处了,去喝口水。