java - 无法使用 Cygwin 从 Java 运行 C 程序

标签 java c windows gcc cygwin

我正在尝试使用 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.
#

我尝试过的:

  1. 编译时使用-mno-cygwin 标志,但由于我安装了最新版本的Cygwin,它不再受支持。

  2. 使用 -mno-cygwin 标志和 gcc-3 而不是 gcc - 但 Cygwin 无法识别 gcc-3命令。

  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/

相关文章:

c++ - 从 Windows 上的 C++ 或 Python 的串口读取

java - 使用替代摘要方法配置基于容器的身份验证

java - 如何使用 JDBI 的 Sql 对象 API 在运行时创建动态 Sql 查询?

c - goto 和 c 中的自动变量初始值设定项

C 预处理器宏

c# - 如何使用 C# SendKeys 以编程方式按下 Windows 键

windows - 如何使用 Visual Studio 进行修补程序部署?

java - 跨平台和跨语言的客户端/服务器应用程序连接

java - @ApplicationScoped 在集群中

c - 将 C 代码编译为裸机(树莓派)时我做错了什么?