我正在尝试使用 JNI 编写我的第一个 Java/C 程序。这是“我的”代码的样子——它是从 this 复制的网站:
/* HelloWorld.java */
public class HelloWorld {
native void helloFromC();
static {
System.loadLibrary("ctest");
}
static public void main(String argv[]) {
HelloWorld helloWorld = new HelloWorld();
helloWorld.helloFromC();
}
}
C 部分:
/* ctest.c */
#include <jni.h>
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloWorld_helloFromC
(JNIEnv * env, jobject jobj)
{
printf("Hello from C!\n");
}
通过Cygwin,我成功了
javac HelloWorld.java
javah HelloWorld
创建这样的头文件:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: helloFromC
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_helloFromC
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
到目前为止一切顺利。我还可以使用以下方法编译 C 程序:
$ gcc -D __int64="long long" -shared -I"D:\Programy\Java\JDK 8u31\include"
-I"D:\Programy\Java\JDK 8u31\include\win32" ctest.c -o ctest.dll
现在应该可以了
java HelloWorld
查看 C 的输出,但我收到此错误:
$ java HelloWorld
#
# A fatal error has been detected by the Java Runtime Environment:
#
# EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000018011ae47, pid=3156, tid=1176
#
# JRE version: Java(TM) SE Runtime Environment (8.0_31-b13) (build 1.8.0_31-b13)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.31-b07 mixed mode windows-amd64 compressed oops)
# Problematic frame:
# C [cygwin1.dll+0xdae47]
#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# D:\Dokumenty\Fifth\src\hs_err_pid3156.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
我尝试过的:
编译时使用
-mno-cygwin
标志,但由于我安装了最新版本的Cygwin,它不再受支持。使用
-mno-cygwin
标志和gcc-3
而不是 gcc - 但 Cygwin 无法识别 gcc-3命令。添加环境变量。这似乎是常见的解决方案,但不知何故它对我不起作用。在我的系统上,Cygwin 安装在
D:\Programy\Cygwin
中,因此我添加到PATH
的文件夹是D:\Programy\Cygwin\bin
,如图picture (对于外部链接抱歉,我没有足够的声誉来发布图片)。
从我读过的所有答案来看,这个应该有效,但它没有。 Cygwin 不是直接在 C:\Cygwin 中有问题吗?还是我做错了什么?我检查了文件夹,是 cygwin1.dll,它没有丢失。
我在 64 位 Windows 8 上运行。 Cygwin 版本:1.7.35-1,安装了整个 Devel 包。 GCC 版本为 4.9.2。
抱歉发了这么长的帖子,我只是想提供尽可能多的信息。我已经被这个问题困扰好几天了,很高兴收到任何建议。
编辑: 我刚刚注意到使用 gcc
命令编译我的 C 文件并没有生成任何可执行文件,我觉得这很奇怪。它也不会抛出任何错误或警告。对此有什么想法吗?这会是我麻烦的根源吗?
编辑 2:我刚刚发现这应该不是问题,我实际上是在制作库,而不是可执行文件。
编辑 3: 好吧,我放弃了。这似乎比我最初想象的要大得多。无法完成此操作的原因是 cygwin1.dll
无法动态加载,因为它在初始化时需要 4k 底部堆栈字节空闲 - 如果从 JNI 调用它可能会出现问题。 有一些方法可以克服它;如果您正在寻找解决方案,this post很好地总结了需要做什么和this one也很有用。对于我的项目,这不值得 - 但祝你好运。
最佳答案
我发现无法做到这一点的原因是 cygwin1.dll
无法动态加载,因为它在初始化时需要 4k 的底部堆栈字节空闲 - 这可能是一个问题如果它是从 JNI 调用的。
有一些方法可以克服它;如果您正在寻找解决方案, this post 很好地总结了需要做什么和 this one也很有用。我还找到了一个明确的解决方案 here .
关于java - 无法使用 Cygwin 从 Java 运行 C 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29487061/