Iniciar o executável construído pelo CYGWIN a partir do Java no Windows 7 falha com “erro ao carregar bibliotecas compartilhadas:?: Nenhum arquivo ou diretório desse tipo”

O código em questão funcionou em mais ou menos a mesma configuração em versões anteriores do Windows, no entanto, não é conhecido por ter executado no Windows 7 AINDA! É o que preciso resolver agora.

Resumidamente, algum código C executa algumas verificações de configuração e segurança antes de iniciar um programa java, passando alguns dados que seriam quase impossíveis de serem feitos facilmente em Java. O Java, por sua vez, no momento apropriado, lança o mesmo código C que, por sua vez, lança um programa Java diferente. O segundo lançamento do programa precisa ser completamente independente, (pense nohup) daí o segundo lançamento.

O que está acontecendo agora é que o programa C lança o programa Java de maneira comum, mas quando o Java tenta iniciar o programa C, ele comete erros assim:

/cygdrive/c/opt/ST/v3.3/bin/ST.exe: erro ao carregar bibliotecas compartilhadas❓ não é possível abrir o arquivo de object compartilhado: Nenhum arquivo ou diretório

Como o Windows tem sido tão pesado ao longo dos anos, o código C é escrito no ambiente posix do Cygwin, mas tudo o que ele realmente faz são tipos comuns de coisas C (nada sobre ele é exclusivo do Cygwin e, de fato, no passado ele foi construído com ferramentas de desenvolvimento da Microsoft, mas esse ambiente não está disponível no momento). O ambiente do Cygwin adiciona muitos outros grandes benefícios, como o gerenciamento de serviços de linha de comando (cygrunsrv) e um ambiente full-on ‘nix-like (bash, etc). Na verdade, como o Windows mudou a forma como um usuário lança um programa do Java tantas vezes, o Cygwin ajuda a padronizar o código de boot do Java. Aqui está um trecho:

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; } 

(Sim, a estrutura if poderia ser melhor otimizada.)

Nesse caso, “Shell” é igual a:

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

E há um programa de teste para garantir que o código acima e de suporte funcionem bem – ele executa um pouco de programa shell e garante que ele receba de volta o que achava que deveria. Diz:

Verificando a capacidade de executar um programa usando um shell … Sim, os programas shell funcionam bem.

O conteúdo final do cmd é algo como isto:

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

O QUE SUSPEITO:

Eu suspeito que o que está acontecendo é que o arquivo Cygwin1.DLL não está sendo encontrado corretamente. Ele vive em C: /cygwin/bin/cygwin1.dll

OBSERVE QUE tanto o PATH de nível do sistema quanto o Cygwin PATH incluem o caminho para os arquivos .dll do cygwin. Mover uma cópia do cygwin1.dll para o diretório bin no qual o executável de destino reside também não funcionou.

O LD_LIBRARY_PATH prestaria alguma ajuda aqui? Em caso afirmativo, alguma ideia de como isso deve ser definido?

Outras ideias?

Obrigado.

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

Isso não funcionará porque o seu diretório de trabalho é onde você reside quando você executa este comando. Você terá que copiar as dlls dependentes do cygwin para o diretório de onde você as executa. De qualquer forma, você terá que colocar o diretório cygwin bin em sua variável PATH do sistema, não tenho certeza se você quer fazer isso, pode causar o inferno dll.

Além disso, se você estiver usando alguma coisa no seu perfil, você precisa adicionar o parâmetro –login ao bash:

 bash --login -c 

Além disso, imprima o comando final no final, antes de gerar o processo:

 printf('%s\n',cmd) 

Só para ter certeza de que é exatamente o que você quer.

Você também pode executar o programa com strace, se não tiver certeza sobre as dlls que estão sendo referenciadas.

Várias formas.

O cygwin1.dll precisa estar em% WINDIR% \ system32 ou equivalente.

ou

você modificar a variável PATH para adicionar o caminho para cygwin1.dll no ambiente do chamador.

ou

você chama um arquivo .bat que define o ambiente antes de chamar o exe construído pelo cygwin.

ou

você constrói uma versão autônoma do .exe (isto é, sem dependência do cygwin).

Intereting Posts