Pregunta

Estoy llamando a un archivo DLL para pasarle un objeto de función de devolución de llamada. Una de las funciones es la impresión simple. Tengo entonces un ciclo de 100 iteraciones, solo imprimiendo el índice y algunas impresiones después del ciclo.


Aquí está el 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");
}

Aquí está el 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;          
      }
});

La salida son los números 0..41 (SÍ 41 !!! no 99) y luego " en Inicio llamado desde Java " seguido de un horrible accidente:

#
# 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]

He leído mucho (aquí también) pero todavía no puedo encontrar el problema. Estoy ejecutando JRE de Java6. Tengo 1,5 GB de memoria en mi máquina. La DLL no es utilizada por ningún otro proceso (sin problemas de concurrencia).

Gracias Azriel

¿Fue útil?

Solución

Intente escribir su MyCallback como com.sun.jna.Callback en su lugar como 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);
  }

Saludos, Emmanuel Girard

Otros consejos

En mi caso, el desarrollo de una aplicación de telecomunicaciones que utiliza un win32 dll fue el caso contrario.

Al usar com.sun.jna.Library y com.sun.jna.Callback, siempre se bloqueaba la VM al regresar de la llamada de devolución de llamada.

Después de cambiar a com.sun.jna.win32.StdCallLibrary y com.sun.jna.win32.StdCallLibrary.StdCallCallback, el problema se resolvió.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top