无法使用Cygwin从Java运行C程序 [英] Cannot run C program from Java using Cygwin

查看:78
本文介绍了无法使用Cygwin从Java运行C程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用JNI制作我的第一个Java/C程序.这是我的"代码的外观-从网站复制而来:

I'm trying to make my first Java/C program using JNI. Here's how 'my' code looks - it's copied from this website:

/* 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,我成功做到了

Through Cygwin, I succesfully did

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程序:

So far so good. I can also compile the C program using:

$ 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的输出,但我却收到此错误:

to see output from C, but instead I'm getting this error:

$ 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,因此不再受支持.

  1. Using -mno-cygwin flag when compiling, but since I have the newest version of Cygwin installed, it's not supported anymore.

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

Using -mno-cygwin flag with gcc-3 instead of gcc - but Cygwin doesn't recognize gcc-3 command.

添加环境变量.这似乎是常见的解决方案,但是对于我来说不起作用.在我的系统上,Cygwin安装在 D:\ Programy \ Cygwin 中,因此我添加到 PATH 的文件夹是 D:\ Programy \ Cygwin \ bin ,如图片所示(对不起,外部链接,我没有有足够的声誉来发布图片).

Adding an environment variable. This seems to be the common solution, but somehow it doesn't work for me. On my system, Cygwin is installed in D:\Programy\Cygwin, therefore the folder I added to PATH is D:\Programy\Cygwin\bin, as shown in the picture (sorry for external link, I don't have enough reputation to post pictures).

从我读过的所有答案来看,这个应该有效,但事实并非如此.Cygwin不在C:\ Cygwin中存在问题吗?还是我做错了其他事?我检查了文件夹,然后找到 cygwin1.dll,它没有丢失.

From all the answers I've read, this one should work, but it doesn't. Is there a problem with Cygwin not being directly in C:\Cygwin? Or am I doing something else wrong? I checked the folder and there is cygwin1.dll, it's not missing.

我正在Windows 8(64位)上运行.Cygwin的版本:1.7.35-1,安装了整个Devel软件包.GCC版本是4.9.2.

I'm running on Windows 8, 64-bit. Version of Cygwin: 1.7.35-1, installed the whole Devel package. GCC version is 4.9.2.

很抱歉,我只想提供尽可能多的信息.我已经被这个问题困扰了好几天了,很乐意提供任何建议.

我刚刚注意到,使用上述 gcc 命令编译C文件不会产生任何可执行文件,我觉得这很奇怪.它还不会引发任何错误或警告.关于这个有什么想法吗?那可能是我麻烦的根源吗?

I just noticed that compiling my C file with gcc command as above doesn't produce any executable file, which I find very strange. It also doesn't throw any error or warning. Any ideas on this one? Could that be the source of my trouble?

我刚刚发现这应该不是问题,我实际上是在制作一个库,而不是一个可执行文件.

Edit 2: I just found out this should not be an issue, I'm actually making a library, not an executable file.

好的,我放弃了.这个问题似乎比我最初想象的要大得多.无法完成此操作的原因是 cygwin1.dll 无法动态加载,因为初始化时它需要4k的底部堆栈字节才能释放-如果从JNI调用它可能会出现问题.有 种方法可以克服它;如果您正在寻找解决方案,请

Edit 3: Okay, I'm giving up. It seems like much bigger issue than I initially thought it would be. The reason this cannot be done is that cygwin1.dll cannot be dynamically loaded, because it needs 4k of bottom stack bytes to be free when it's initializing - which might be a problem if it's being called from JNI. There are some ways to overcome it; if you're looking for a solution, this post sums up nicely what needs to be done and this one can also be useful. For my project, it's just not worth it - but good luck.

推荐答案

我发现无法完成此操作的原因是 cygwin1.dll 无法动态加载,因为它需要4k的底部堆栈初始化时要释放的字节数-如果从JNI调用它可能会出现问题.

I found that the reason this cannot be done is that cygwin1.dll cannot be dynamically loaded, because it needs 4k of bottom stack bytes to be free when it's initializing - which might be a problem if it's being called from JNI.

一些方法可以克服它;如果您正在寻找解决方案,请 此处找到了明确的解决方案.

There are some ways to overcome it; if you're looking for a solution, this post sums up nicely what needs to be done and this one can also be useful. I also found an explicit solution here.

这篇关于无法使用Cygwin从Java运行C程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆