2010-11-27 14 views
7

¿Cómo puedo llamar a un método con esta firma de método en C de JNA?¿Cómo obtener un nuevo puntero en Java?

int open_device(context *ctx, device **dev, int index); 

Las dos últimas líneas del método C se ven así:

*dev = pdev; 
return 0; 

Ese es el único uso de dev en ese método. Eso significa que tengo que pasar un poiner a un puntero vacío para el método, ¿verdad? El método luego llena el puntero vacío con la dirección de un objeto device y puedo pasar el puntero al dispositivo a otros métodos.

Mi pregunta es: ¿Es esta la manera correcta de hacerlo? Si es así, ¿cómo puedo asignar un nuevo puntero desde Java?


Sobre la base de la respuesta aceptada, lo hice:

Memory p = new Memory(Pointer.SIZE); 
Memory p2 = new Memory(Pointer.SIZE); 
p.setPointer(0, p2); 
nativeLib.open_device(ctx, p, index); 
return p2; 
+0

Sólo curiosidad: ¿su código actualizado funciona para usted? Parece que está configurando '* p = p2' pero luego la función C haría' * p = pdev', sobrescribiendo así el valor. – casablanca

+0

@casablanca: Sí, lo probé, funciona. – thejh

+0

@thejh ¿sabe cómo manejar la excepción de AccessMemory no válida creada debido a direcciones de memoria no válidas? – mayooran

Respuesta

9

Parece que la clase JNA Pointer tiene setPointer y getPointer métodos para permitir el direccionamiento indirecto múltiple, y la clase Memory a realidad "asignar" objetos nativos. Por lo que debe ser capaz de hacer algo como: (Sólo estoy adivinando a partir de los documentos JNA, no he probado esto)

Pointer pDev = new Memory(Pointer.SIZE); // allocate space to hold a pointer value 
// pass pDev to open_device 
Pointer dev = pDev.getPointer(0);  // retrieve pointer stored at pDev 
+0

Ah, esa 'nueva memoria (Pointer.SIZE);' parece que es lo que necesito, gracias. – thejh

0

No hay punteros en Java, sólo referencias.

No puede reasignar una referencia cuando las pasa a métodos, porque las pasa por valor. Todo se pasa por valor en Java.

Puede volver a escribir este método para crear una nueva instancia del dispositivo y devolverlo en lugar de un int.

+3

@duffymo: Estaba hablando de JNA Pointers: https://jna.dev.java.net/javadoc/com/sun/jna/Pointer.html – thejh

+0

Es posible hacer esto sin JNA. Solo tiene que devolver la nueva referencia al objeto Device que instancia en lugar de un int. – duffymo

+2

@duffymo: ¿Y cómo puedo acceder a una biblioteca c (libbla.so) usando Java sin estas cosas explícitamente nativas? – thejh

0

Aún mejor respuesta. Es posible que desee asignar (malloc, etc.) según la longitud de la cadena Java. El siguiente ejemplo es la prueba unitaria del proyecto JNA.

public void testGetSetStringWithDefaultEncoding() throws Exception { 
    final String ENCODING = Native.DEFAULT_ENCODING; 
    String VALUE = getName(); 
    int size = VALUE.getBytes(ENCODING).length+1; 
    Memory m = new Memory(size); 
    m.setString(0, VALUE); 
    assertEquals("Wrong decoded value", VALUE, m.getString(0)); 
} 
Cuestiones relacionadas