首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用Cygwin从Java运行C程序

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

Stack Overflow用户
提问于 2015-04-07 08:25:02
回答 4查看 1.1K关注 0票数 6

我正在尝试使用JNI制作我的第一个Java/C程序。下面是“我的”代码的外观--它是从网站复制的:

代码语言:javascript
复制
/* 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部分:

代码语言:javascript
复制
/* ctest.c */

#include <jni.h>
#include <stdio.h>

JNIEXPORT void JNICALL Java_HelloWorld_helloFromC
  (JNIEnv * env, jobject jobj)
{
    printf("Hello from C!\n");
}

通过Cygwin,我成功地做到了

代码语言:javascript
复制
javac HelloWorld.java
javah HelloWorld

要创建这样的头文件:

代码语言:javascript
复制
/* 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程序:

代码语言:javascript
复制
$ 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

现在我应该能做到

代码语言:javascript
复制
java HelloWorld 

要查看C的输出,但是我得到了以下错误:

代码语言:javascript
复制
$ 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,如图片中所示(对不起,外部链接,我没有足够的声誉发布图片)。

从我所读到的所有答案中,这个应该是有效的,但它没有。Cygwin没有直接出现在C:\Cygwin中有问题吗?还是我做错了什么?我检查了文件夹,发现了cygwin1.dll,它没有丢失。

我在运行Windows 8,64位。Cygwin的版本: 1.7.35-1,安装了整个开发包.GCC版本为4.9.2。

很抱歉,我只是想提供尽可能多的信息。我已经被这个问题困扰了好几天了,如果有任何建议我会很高兴的。

编辑:--我刚刚注意到,像上面这样用gcc命令编译C文件不会产生任何可执行文件,我觉得这很奇怪。它也不会抛出任何错误或警告。对这个有什么想法吗?这会是我麻烦的根源吗?

编辑2:我刚刚发现这不应该是一个问题,我实际上是在创建一个库,而不是一个可执行文件。

编辑3:,好了,我放弃了。这似乎比我最初想象的要大得多。之所以不能这样做,是因为cygwin1.dll不能被动态加载,因为它需要4k的底层堆栈字节才能在初始化时释放--如果从JNI调用它,这可能是一个问题。有一些方法可以克服它;如果您正在寻找解决方案,这个职位很好地总结了需要做的事情,这一个也可能很有用。对于我的项目,这是不值得的-但祝你好运。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-04-09 08:20:53

我发现不能这样做的原因是cygwin1.dll不能被动态加载,因为它需要4k的底层堆栈字节才能在初始化时释放--如果从JNI调用它,这可能是一个问题。

有一些方法可以克服它;如果您正在寻找解决方案,这个职位很好地总结了需要做的事情,这一个也可能很有用。我还找到了一个显式的解决方案这里

票数 5
EN

Stack Overflow用户

发布于 2015-04-07 08:33:14

在c文件中添加使用javah生成的头文件

代码语言:javascript
复制
/* ctest.c */
#include "HelloWorld.h"
#include <jni.h>
#include <stdio.h>

JNIEXPORT void JNICALL Java_HelloWorld_helloFromC
(JNIEnv * env, jobject jobj)
{
printf("Hello from C!\n");
}

并使用

代码语言:javascript
复制
java -Djava.library.path=. HelloWorld

如果它不起作用,那就试试

代码语言:javascript
复制
java HelloWorld

本站中解释了一个更详细的例子

票数 2
EN

Stack Overflow用户

发布于 2015-04-07 14:48:27

由于我不能以我的低声誉发表评论,所以我会在这里说出来。

  1. 在cmd中echo %PATH%的结果是什么,您清楚地看到到Cygwin的二进制文件的路径吗?
  2. java HelloWorld之后,D:\Dokumenty\Fifth\src\hs_err_pid3156.log中的日志内容是什么?

我会在你的答案之后编辑这个答案。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29487061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档