MinGW-GCC 如何编译JNI程序

第一步:编写java程序
public class HelloWorld {
    public native void displayHelloWorld();

    static {
        System.loadLibrary("hello");
    }

    public static void main(String[] args) throws Exception {
        new HelloWorld().displayHelloWorld();
    }
}
注意其中的代码
    public native void displayHelloWorld();
    就是声明displayHelloWorld()这个方法是本地方法,需要在jni中实现。
    static {
        System.loadLibrary("hello");
    }
    意思是载入库文件,意味着我们下面的jni程序最终需要打包成hello.dll

第二步:编译java程序
javac HelloWorld.java

第三步:生成头文件
javah -jni HelloWorld

第四步:编写本地实现代码
我们打开第三步生成的HelloWorld.h这个文件,找到其中的方法声明
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld
  (JNIEnv *, jobject);
这是jni的命名规范,具体
可以参考java tutorial。这里只是方法声明,现在我们来实现它。
/*  HelloWorldImp.c  */
#include <jni.h>
#include "HelloWorld.h"
#include <stdio.h>

JNIEXPORT void JNICALL 
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj) 
{
    printf("Hello world!\n");
    return;
}

第五步:创建库文件
前面第一步里面提到过hello.dll,这里利用以前提到的制作动态库的命令来生成它。

注意如果是64位系统,请下载64位mingw
gcc -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 -shared -o hello.dll HelloWorldImp.c
运行
java HelloWorld


如果程序报错
Exception in thread "main" java.lang.UnsatisfiedLinkError: displayHelloWorld
        at HelloWorld.displayHelloWorld(Native Method)
        at HelloWorld.main(HelloWorld.java:9)
意思是库文件已经成功载入了,但是没有找到相匹配的displayHelloWorld这个方法。可是我们明明实现了这个方法的呀?原来程序在调用动态库的时候,没有我们想象中的那么简单,而且不同的编译器做法不一样,windows版java中调用jni遵从的是vc的调用方式,和我们用的MinGW GCC默认格式不一致。我们需要调整一下参数,(注意其中的--kill-at)


gcc -I%JAVA_HOME%\include -I%JAVA_HOME%\include\win32 -shared -Wl,--kill-at -o hello.dll HelloWorldImp.c

(如果JDK装在C:\Program Files目录下,可能会因为空格而找不到目录可将include里的jni.h和jni_md.h复制到别的文件夹如-Ic:/jni)

运行

java HelloWorld


Hello world! 运行成功,great  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值