2

有问题的代码在早期版本的 Windows 上或多或少地以完全相同的配置工作,但是,尚不清楚它是否已在 Windows 7 上运行!这就是我现在需要解决的问题。

简而言之,一些 C 代码在启动 java 程序之前执行一些配置和安全检查,传递一些在 Java 中几乎不可能轻易完成的数据。反过来,Java 在适当的时候启动相同的 C 代码,然后它自己启动不同的 Java 程序。第二个程序启动需要完全独立,(想想 nohup)因此是第二次启动。

现在发生的情况是 C 程序以普通方式启动 Java 程序,但是当 Java 尝试启动 C 程序时,它会出现如下错误:

/cygdrive/c/opt/ST/v3.3/bin/ST.exe:加载共享库时出错:?:无法打开共享对象文件:没有这样的文件或目录

因为多年来 Windows 一直是个熊,所以 C 代码是在 Cygwin 的 posix 环境中编写的,但它真正做的只是普通的 C 类型的东西(它没有什么是 Cygwin 独有的,事实上,在过去它已使用微软的开发工具构建,但该环境目前不可用)。Cygwin 环境增加了许多其他巨大的好处,例如服务的命令行管理 (cygrunsrv) 和完整的类 nix 环境(bash 等)。事实上,由于 Windows 已经多次改变了从 Java 启动程序的方式,Cygwin 有助于标准化 Java 启动代码。这是一段摘录:

  if (ClientOS.indexOf("Windows") != -1)
  {
     if (ClientOS.equals("Windows 95"))
     {
        cmd = "command.com /C ";
     } else if (ClientOS.equals("Windows 98"))
     {
        cmd = "command.com /C ";
        //cmd = "cmd.exe /C ";
     } else if (ClientOS.equals("Windows NT"))
     {
        cmd = "cmd.exe /C ";
     } else if (ClientOS.equals("Windows 2000"))
     {
        cmd = "cmd.exe /C ";
     } else if (ClientOS.equals("Windows XP"))
     {
        cmd = "cmd.exe /C ";
     } else {
        cmd = "cmd.exe /C ";
     }
     if (cygwin)
     {
        cmd += Shell+" '"+Command+"'";
     } else {
        cmd += Command;
     }
  } else {
     cmd = Command;
  }

(是的,if 结构可以更好地优化。)

在这种情况下,“外壳”等于:

Shell=C:/cygwin/bin/bash -c

而且,有一个测试程序可以确保上述代码和支持代码正常工作 - 它运行一些 shell 程序并确保它得到它认为应该的东西。它说:

检查使用 shell 运行程序的能力...是的,shell 程序可以正常工作。

cmd 的最终内容如下所示:

cmd.exe /CC:/cygwin/bin/bash -c '/cygdrive/c/opt/ST/v3.3/bin/ST.exe'

我怀疑:

我怀疑发生了什么是 Cygwin1.DLL 文件没有被正确找到。它位于 C:/cygwin/bin/cygwin1.dll

注意系统级 PATH 和 Cygwin PATH 都包含 cygwin .dll 文件的路径。将 cygwin1.dll 的副本移动到目标可执行文件所在的 bin 目录也不起作用。

LD_LIBRARY_PATH 会在这里提供帮助吗?如果是这样,知道如何设置吗?

其他想法?

谢谢。

4

2 回答 2

0

几种方式。

cygwin1.dll 需要位于 %WINDIR%\system32 或同等位置。

或者

您修改 PATH 变量以在调用者的环境中添加 cygwin1.dll 的路径。

或者

在调用 cygwin 构建的 exe 之前调用设置环境的 .bat 文件。

或者

您构建一个独立版本的 .exe(即没有 cygwin 依赖项)。

于 2012-04-10T17:12:43.523 回答
0
C:/cygwin/bin/bash -c '/cygdrive/c/opt/ST/v3.3/bin/ST.exe'

这不起作用,因为您的工作目录是您执行此命令时所在的位置。您必须将依赖 cygwin 的 dll 复制到执行此操作的目录中。否则,您必须将 cygwin bin 目录放在系统 PATH 变量中,不确定您是否要这样做,这可能会导致 dll 地狱。

此外,如果您在配置文件中使用任何内容,则需要将 --login 参数添加到 bash:

bash --login -c

此外,在生成进程之前,在最后打印出最终命令:

printf('%s\n',cmd)

只是为了确保它正是你想要的。

如果您不确定引用的 dll,您也可以使用 strace 运行该程序。

于 2012-04-10T16:52:08.730 回答