当前位置:首页 > CN2资讯 > 正文内容

我的世界JAVA版环境错误

8小时前CN2资讯


零 绪论

今天看安卓的源码。发现很多东西都是jni的东西。所以我也要看看java是怎么和jni通信的。那么就涉及到了编译问题。这种情况下涉及到交叉编译,很烦。网络上也是哀嚎声一片。但是我没有遇到那么多的困难。

首先注意几个要点
1你要知道你运行java的程序的版本。我是64位的
2你要知道你gcc编译器编译出来的东西是多少位的
我想很多情况下都是可能gcc编译出来的是32位的东西,你拿到64位jre上运行。可能是这样导致的错误。
说一下我系统的配置情况。
我是采取全线64位策略
win7 64位
jdk 64位
jre64位
mingw64位

下面我一步一步讲解如何编译

一准备

工具准备 win7 jdk64 jre64都是很好弄到的。重点是mingw64.这个东西确保你使用gcc的时候编译出来的是64位的动态链接库,好给64位的jre使用。
其中mingw64很难再官网上下载,所以我是在一个
这里下载出来的

下载出来是个压缩包把压缩包里面的


解压出来。我放到了D:\Program Files里面

至此你的mingw64已经安装完成。为了能在cmd里面找到你的gcc。你需要把

D:\Program Files\mingw64\bin

这个路径添加到你的path环境变量里面。如何添加环境变量另行百度。

这样你的gcc方面已经配置好。

二 编译

1准备测试代码

下面给出测试代码。这个代码随处可见

//HelloNative.java class HelloNative { public static native void greeting(); }

用javac编译这个产生HelloNative.class命令如下

javac HelloNative.java

如果找不到javac命令在哪里。那么说明你的jdk没有放到path变量里面。解决方法和把gcc放到path里面一样

你需要运行javah命令,根据HelloNative.class生成一个用于编写c的头文件

javah HelloNative

这时候会产生一个这样的文件HelloNative.h
内容是

/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class HelloNative */ #ifndef _Included_HelloNative #define _Included_HelloNative #ifdef __cplusplus extern "C" { #endif /* * Class: HelloNative * Method: greeting * Signature: ()V */ JNIEXPORT void JNICALL Java_HelloNative_greeting (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif

这个是自动生成的头文件。现在你需要自己编写一个c文件,实现这个native代码

//名字是HelloNative.c #include<stdio.h> #include"HelloNative.h" JNIEXPORT void JNICALL Java_HelloNative_greeting(JNIEnv* env,jclass cl) { printf("hello native"); }

到这里之后。你的c文件也准备好编译了。

2编译出dll

如果简单的运行下面的命令是无法编译出来的

gcc HelloNative.c

错误有几个方面
1我们要生成一个连接库,并不是一个exe文件。
所以要加上参数-shared -o helloNative.dll HelloNative.c
这里的-shared是说我们要一个动态链接库 -o helloNative.dll指定我输出出来的名字
现在命令是这个样子

gcc -shared -o helloNative.dll HelloNative.c

2我们引用了jni这个头文件,但是标准的c里面没有这个头文件,我们需要指定说这个头文件去哪里找。我们要添加
-IC:\Java\jdk1.8.0_60\include
-IC:\Java\jdk1.8.0_60\include\win32
这两个参数可能你会有变化。因为我的jdk安装在C:\Java\jdk1.8.0_60\。所以自然我们就需要指定搜索路径是C:\Java\jdk1.8.0_60\include 。 -I表示头文件搜索路径
现在的编译命令是这样的

gcc -IC:\Java\jdk1.8.0_60\include -IC:\Java\jdk1.8.0_60\include\win32 -shared -o helloNative.dll HelloNative.c

当然还有很多奇怪的问题
我们要加参数
-Wl,–kill-at
其实-WI是告诉gcc后面的参数–kill-at是给链接器的
–kill-at告诉链接器功能如下。

–kill-at
If given, the stdcall suffixes (@nn) will be stripped from symbols before they are exported.
[This option is specific to the i386 PE targeted port of the linker]

下面是个网友的解释

On Microsoft systems (PE executable/DLL format), the calling convention stdcall generates mangled symbols of the form symbolname@number. From the description, –kill-at causes the names exported from DLLs to just be symbolname even if they use the stdcall calling convention.
就是说在链接库里面的函数名字表示方式要做改变。不然jvm不能识别。

-D_JNI_IMPLEMENTATION_

这个选项的意思是-D是告诉gcc后面的东西定义一个宏。

gcc -D选项在man中的说明如下:
-D name
Predefine name as a macro, with definition 1.

还有加上一个参数-Wall
这个参数说

-Wall
This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with macros. This also enables some language-specific warnings described in C++ Dialect Options and Objective-C and Objective-C++ Dialect Options.

就是打开所有警告。好像可以关闭的样子

现在我终极的编译命令是

gcc -Wall -D_JNI_IMPLEMENTATION_ -Wl,–kill-at -IC:\Java\jdk1.8.0_60\include -IC:\Java\jdk1.8.0_60\include\win32 -shared -o helloNative.dll HelloNative.c

总算完成了

编译之后会产生一个文件叫helloNative.dll

三测试

我们可以写一个测试文件

//test.java public class test { public static void main(String args[]) { HelloNative.greeting(); } static { System.loadLibrary("helloNative"); } }

然后编译运行这个文件我们可以得到这样的结果

备注

1我们所有的代码都是放到C的根目录下面的

2目录内容如下


    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/31749.html

    分享给朋友:

    “我的世界JAVA版环境错误” 的相关文章

    深入了解俄罗斯时区对生活与经济的影响

    在这个广袤的国家,谈论俄罗斯时区就如同打开了一本极其丰富的地理和文化百科全书。俄罗斯作为世界上面积最大的国家,领土纵深可谓无比广阔,从西欧一直延伸到东亚。这种东西跨度的特性,使得时区的划分显得尤为重要。俄罗斯实际上拥有11个时区,每个时区不仅仅是时间的概念,更承载着各自地区独特的人文、经济和社会习惯...

    如何通过 NameCheap 注册 $0.99 便宜域名并选择合适后缀

    在如今的网络世界,获取一个合适的域名可以说是非常关键的。对我来说,域名不仅是一个网站的门牌,更是品牌的第一印象。最近,NameCheap 推出了一个令人兴奋的优惠活动,注册域名低至 $0.99 每年,这绝对是个让人心动的机会。想到能够以这样的低价拥有一个域名,真的是让我忍不住想赶紧注册。 相信大家对...

    DigitalOcean与Vultr的全面比较与选择建议

    DigitalOcean与Vultr概述 1.1 DigitalOcean简介 DigitalOcean成立于2012年,总部位于美国纽约,这家公司一开始就定位于为开发者提供高效的云计算服务。最初的目标是简化云计算,让更多人能够轻松使用这一新兴技术。随着时间的推移,DigitalOcean不断扩展其...

    选择香港机房的优势与服务:最理想的数据中心解决方案

    在当今数字化的时代,香港机房作为亚洲地区的数据中心枢纽,其重要性愈发凸显。随着全球对高效、安全、稳定数据处理需求的上升,香港凭借其优越的地理位置和完善的网络基础设施,已成为众多企业首选的托管与服务器服务地点。以高速网络连接、优质的BGP多线路接入以及高标准的设施著称,香港机房为客户提供了一系列的解决...

    IP检测服务:简化网络体验与保护用户隐私

    IP检测服务是当今网络环境中不可或缺的一部分。简单来说,它帮助用户或开发者迅速获取他们的设备公网IP地址,同时提供各种网络信息。这项服务以其高效、便捷和免费的特点,吸引了众多用户和企业进行使用。 想获取公网IP地址往往需要复杂的步骤,而IP检测服务的出现使这个过程变得轻松。它支持多种返回格式,包括纯...

    搬瓦工查看流量使用的最佳方法与管理策略

    在使用搬瓦工(BandwagonHost)这家VPS提供商时,了解流量的相关信息是非常重要的。搬瓦工的流量套餐设计十分灵活,满足了不同用户的需求。每个VPS方案都设有流量限制,比如每月500GB或1TB,这些限制会直接影响到我们如何使用这些资源。用户在选择方案时,应该充分考虑自己的日常使用习惯,以便...