Pergunta

Eu estou chamando uma DLL com a passagem de um objeto de retorno de chamada functio a ele. Uma das funções é simples impressão. Eu tenho seguida, um loop de 100 iterações, apenas imprimir o índice e algumas impressões após o loop.


Aqui está o código C

extern "C" int Start(void* callback(CString))
{
   for(int j=0; j<100; j++)
    callback(AConvertToString(j));

   callback("in Start called from Java");
   callback("another line");
}

Aqui está o código Java

public interface MyDll extends Library{
  MyDll INSTANCE = (MyDll) Native.loadLibrary("MyDll",MyDll.class);
     public interface MyCallback extends StdCallCallback {
            public boolean callback(String msg);
     }
     public int Start(MyCallback callback);
  }

//in main:
...
  MyDll myDll = (MyDll)MyDll.INSTANCE;
  myDll.Start(new MyDll.MyCallback() {
      public boolean callback(String msg) {
         System.out.println(msg);
          return true;          
      }
});

A saída é números 0..41 (sim 41 !!! não 99) e, em seguida, "em Iniciar chamada de Java" seguido por um acidente horrível:

#
# An unexpected error has been detected by Java Runtime Environment:
#
#  EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x7c809823, pid=468, tid=2636
#
# Java VM: Java HotSpot(TM) Client VM (10.0-b23 mixed mode, sharing windows-x86)
# Problematic frame:
# C  [kernel32.dll+0x9823]

Eu li um monte (aqui também) mas não consigo encontrar o problema. Estou executando o JRE de Java6. Eu tenho 1,5 GB de memória em minha máquina. O DLL não é usado por qualquer outro processo (sem problemas de concorrência).

Obrigado, Azriel

Foi útil?

Solução

Tente escrever seu meuCallBack como um com.sun.jna.Callback vez como um com.sun.jna.win32.StdCallLibrary.StdCallCallback:

public interface MyDll extends Library{
  MyDll INSTANCE = (MyDll) Native.loadLibrary("MyDll",MyDll.class);
     public interface MyCallback extends Callback {
            public boolean callback(String msg);
     }
     public int Start(MyCallback callback);
  }

Saudações, Emmanuel Girard

Outras dicas

No meu caso desenvolvendo um aplicativo de telecomunicações que utiliza uma DLL Win32 foi o caso oposto.

Usando com.sun.jna.Library e com.sun.jna.Callback sempre bateu o VM quando voltar da chamada de retorno de chamada.

Depois de mudar para com.sun.jna.win32.StdCallLibrary e com.sun.jna.win32.StdCallLibrary.StdCallCallback o problema foi resolvido.

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