Pergunta

Estou a escrever algum código JNI em C ++ para ser chamado a partir de um applet no Windows XP. Eu tenho sido capaz de executar com êxito o applet e ter a biblioteca JNI carregado e chamado, mesmo indo tão longe como tendo-o chamar funções em outras DLLs. Eu tenho esse trabalho, definindo a variável de ambiente do sistema PATH para incluir o diretório todos os meus DLLs estão em.

Assim, o problema, é que eu adicionar outra chamada que usa uma nova DLL externo, e de repente quando o carregamento da biblioteca, um UnsatisfiedLinkError é lançada. A mensagem é: 'O procedimento especificado não pôde ser encontrado'. Este não parece ser um problema com uma DLL dependente faltando, porque eu posso remover uma DLL dependente e receber uma mensagem diferente sobre DLL dependentes faltando. Pelo que tenho sido capaz de encontrar on-line, parece que este meio de mensagens que uma implementação nativa função Java está faltando no DLL, mas é estranho que ele funciona muito bem sem esse bit extra de código.

Alguém sabe o que pode estar causando isso? Que tipo de coisas pode dar um 'O procedimento especificado não pôde ser encontrado' mensagens para um UnsatisifedLinkError?

Foi útil?

Solução

Eu descobri o problema. Este foi um doozy. A mensagem "O procedimento especificado não pôde ser encontrado" para UnsatisfiedLinkError indica que uma função na dll raiz ou em um dependente dll não pôde ser encontrado. A causa mais provável desse em uma situação JNI é que a função JNI nativo não é exportado corretamente. Mas isso aparentemente pode acontecer se uma DLL dependente é carregado e que DLL está faltando uma função requerida por seu pai.

A título de exemplo, temos uma biblioteca chamada input.dll. A ordem de pesquisa de DLL é olhar sempre no diretório do aplicativo em primeiro lugar e os diretórios PATH últimos. No passado, nós sempre correu executáveis ??do mesmo diretório que input.dll. No entanto, há um outro input.dll no diretório de sistema do Windows (que está no meio da ordem de pesquisa de DLL). Assim, quando executar este a partir de um applet java, se eu incluir o código descrito acima no applet, o que provoca input.dll a ser carregado, ele carrega o input.dll do diretório do sistema. Porque o nosso código está esperando determinadas funções no input.dll que não estão lá (porque é uma DLL diferente) a carga falha com uma mensagem de erro sobre os procedimentos desaparecidas. Não porque as funções JNI são exportados errado, mas porque a DLL dependente errado foi carregado e não têm as funções esperadas na mesma.

Outras dicas

Existe uma possibilidade de que o DLL foi construído usando C ++ (em oposição a C). a menos que você teve o cuidado de fazer uma externa sobre o procedimento, esta é uma razão possível.

Tente exportar todas as funções da DLL. Se a lista inclui a sua função, então você é bom.

Normalmente, quando ligando para outras bibliotecas, você precisa link para o arquivo .lib relevante. Parece que você não está fazendo referência todos os arquivos lib que você precisa. Confira o que não está ligando e certifique-se de adicioná-lo da lib à lista para o vinculador.

Você criar o novo DLL externo usando o procedimento JNI padrão? Ou seja, usando javah e assim por diante? Se assim for, então eu não sei o que está errado.

Se não, então o procedimento que você está tentando chamada não foi exportada (como mencionado por anjanb). Estou ciente de duas vias de funções exportação:. Uma lista de exportação separado e marcação funções específicas com __declspec (dllexport)

Não é possível variável de acesso em C ++ DLL a partir de a C app tem um pouco mais de informação do tema da DLLs.

Compilar seu código C ++ no modo de depuração. Em seguida, inserir o DebugBreak (); declaração onde você gostaria de iniciar a depuração. Executar o código java. Quando a declaração DebugBreak () é encontrado você receberá um pop-up com um botão de depuração sobre ele. Clique nisso. Dev Studio irá abrir com o seu programa em código de máquina. Passar por cima com o depurador duas vezes e você deve ser capaz de passar por cima seu código-fonte.

Se você tiver feito tudo questão de programação em manuais e exemplos JNI, mas ainda você está recebendo mesma falta de erro procedimento, problema pode estar no seu caminho variável provavelmente. Fazer os passos abaixo e execute novamente:

  1. Certifique-se sobre você definir JAVA_HOME variável para a pasta JDK (JRE não porque JRE does not conter cabeçalho JNI) Exemplo: No painel de configurações de variáveis ??de ambiente definir var: JAVA_HOME val: C: \ Arquivos de programas \ Java \ jdk1.7.0_11
  2. add % JAVA_HOME% \ bin a sua variável de caminho

Depois de fazer esses passos, a sua aplicação pode encontrar o nome procedimento jni e links para JNI.dll em caminho certo. Então, eu espero que você não receber esse erro procedimento faltando novamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top