Jni

15 respostas
J

Pessoal eu estou com um problema.

Desenvolvi um programa java que acessa uma DLL feita em JNI/C++ no Visual Studio 2003.

Desenvolvi a classe:

class TerraJava {

/<em>------------------------------- JNI ---------------------------------------------------</em>/

public native static boolean connect(String host, String user, String password, String database, int port, int dbType) ;
static { System.loadLibrary("TerraJava"); }

}

Na minha classe main:

class salvarImagem

{

public static void main(String[] args)

{

TerraJava TeJava = new TerraJava();

}

}

Quando eu rodo o programa, ele da erro na linha que esta o TerraJava TeJava = new TerraJava(); falando o seguinte:

“O sistema operacional não pode executar %1”

Alguém saberia me dizer o que significa isso?
Alguém ja teve esse problema?

Junior Bruno

15 Respostas

Pedrosa

Vc fez todos os procedimentos?, criou o arquivo .h? registrou a dll? fez uma programa em C++ no padrão JNI chamando a tal dll?

J

Sim fiz todos os os procedimentos

Tentei no Visual Studio 2003 e no 2005 e em ambos apresentaram o mesmo problema

Você já passou por isso antes?

Pedrosa

Vc já conseguiu testar essa dll com outra tecnologia para ver se está funcionando?

J

Não testei não, mas em uma outra máquina ja funcionou… estou achando que é alguma configuração da minha maquina…

Pedrosa

Desregistra a dll, registra e tenta de novo, esse erro é muito estranho.

J

Eu esqueci de lhe falar, esse dll não é registrada… e se for ela não esta conseguindo pois quando mando registrar ela não da nenhuma mensagem de erro e muito menos mensagem dizendo que registrou…

Será que tem alguma coisa a ver com a configuração que eu fiz no VS2003???

T

a) DLLs JNI não precisam, não devem e não podem ser registradas.
b) Provavelmente você está usando alguma opção de compilação para a sua DLL que está requerendo que você despache com a sua aplicação algumas outras DLLs, como MSVCRT.DLL e/ou msvcp70.dll ou msvcp71.dll. Isso pode dar muitos problemas; é melhor alterar a opção de compilação para que ele não precise carregar essas DLLs.

Você tem de alterar para usar /MT (na versão Release). Nunca despache a versão Debug para rodar em outra máquina.

Pedrosa

Agora fiquei curioso, fiz um teste aqui com JNI e registrei a dll e funcionou corretamente, mas como vc disse não a é melhor maneira, qual seria então? Seria apontar no path do Windows a jvm.dll e xxx.dll junto com a dll em padrão JNI?

E quais problemas posso ter ao registrar tal dll?

T

Uma DLL do Windows só pode ser registrada se ela tiver duas entradas (entry points):
DLLRegisterServer -> grava a informação da DLL no Registry para o COM usar
DLLUnregisterServer-> limpa a informação da DLL no Registry para o COM usar

Nesse caso, quando você registra ou desregistra (com RegSrv32), você na verdade chama uma dessas entradas da DLL. Isso só é útil quando você tem uma DLL que pode ser chamada a partir do COM+, ou então a partir de um programa VB 6.0 ou Delphi.

T

Eu já vi gente que escreve DLLs que podem ser chamadas de um monte de jeitos: via JNI, via COM ou então como se fosse uma DLL antiga (que você carrega no C++ com uma .LIB mesmo). Pode ser que você tenha uma DLL dessas, que pode fazer tudo (assobiar e chupar cana).

J

Pessoal, fiz tudo o que vcs falaram mas até agora não consegui… estou anexando o resultado…

T

a) Cheque se sua DLL tem realmente os pontos de entrada corretos.
Isso pode ser feito da seguinte maneira:

  • No item do menu Microsoft Visual Studio 2005 (ou Microsoft Visual Studio .NET 2003) existe um submenu Visual Studio Tools, e então uma entrada Microsoft Visual Studio Command Prompt. Isso lhe dá um Command Prompt (linha de comando do DOS) que já está com o path correto para chamar a ferramenta dumpbin.

Vou dar um exemplo para a DLL JNI jpeg.dll (que está em C:\arquivos de programas\jre1.5.0_06\bin)

dumpbin /exports jpeg.dll | more

A saída é algo como:
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file jpeg.dll

File Type: DLL

  Section contains the following exports for jpeg.dll

    00000000 characteristics
    4373A761 time date stamp Thu Nov 10 17:02:41 2005
        0.00 version
           1 ordinal base
          25 number of functions
          25 number of names

    ordinal hint RVA      name

          1    0 000034FA _JNI_OnLoad@8
          2    1 000026C1 _Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_abo
rtRead@16
          3    2 00002859 _Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_dis
poseReader@16
          4    3 000017BD _Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_ini
tJPEGImageReader@8
          5    4 00001676 _Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_ini
tReaderIDs@20
          6    5 00001DFA _Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_rea
dImage@80
          7    6 00001B97 _Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_rea
dImageHeader@24
          8    7 000026FC _Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_res
etLibraryState@16
          9    8 00002724 _Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_res
etReader@16
         10    9 00001DD1 _Java_com_sun_imageio_plugins_jpeg_JPEGImageReader_set
OutColorSpace@20

Ou seja, suas APIs JNI devem aparecer como Java<nome da classe><nome do método>@<número de bytes gastos para empilhar os parâmetros>

T

b) Ponha sua DLL em c:\windows\system32 e tente rodar o programa fora do JCreator.

Pedrosa

Desculpe Thingol, vc estava certo ele nem deixa registrar a dll, simplesmente está na pasta system32.

J

Pessoal.

Não tive muito tempo na semana passada para agradecer a ajuda oferecida por vcs, mas faço agora.

Muito obrigado mesmo… descobri que o problema era mais simples do que imaginava.

A minha dll dependia de uma outra e essa outra estava desatualizada.

Valeu.

Criado 22 de maio de 2006
Ultima resposta 1 de jun. de 2006
Respostas 15
Participantes 3