Linux, JNA: UnsatisfiedLinkError en la segunda llamada al método liblo

Me gusta controlar 'sooperlooper' desde java, un looper de sonido. Esto usa el protocolo OSC. El primer intento fue la biblioteca Java OSC, pero esto no hace nada. Ahora estoy tratando de JNA para envolver liblo.so

El programa que intento replicar en JAVA es muy simple (por supuesto, con diferentes comandos de "registro"):

static lo_address addr;

int main(int argc, char *argv[])
{
        addr = lo_address_new(<IP>, "9951");
        lo_send(addr, "/sl/-1/down", "s", "record");
}

La declaración C del método erróneo es ( https://github.com/radarsat1/liblo/blob/master/lo/lo.h.in ):

int lo_send(lo_address targ, const char *path, const char *type, ...);

Si entiendo correctamente, lo_address es un tipo de puntero vacío declarado en otro lugar. La interfaz de mi biblioteca es:

public interface LibLo extends Library {
    Pointer lo_address_new(String host, String port);
    int lo_send(Pointer address, String command, String a, String... params);
}

Y mi código de llamada es este:

System.setProperty("jna.debug_load", "true");
System.setProperty("jna.debug_load.jna", "true");
LibLo libLo = Native.loadLibrary("liblo", LibLo.class);

Pointer pointer = libLo.lo_address_new(<IP>, "9951");
libLo.lo_send(pointer, "/sl/-1/down","s", "record");

Atraviesa perfectamente la llamada lo_address_new. 'puntero' tiene algún valor. Creo que mis argumentos son correctos. Y descubrí que incluso con argumentos incorrectos, pasa la llamada lo_address_new.

Mi stdout es:

...
Found library 'liblo' at /usr/lib/x86_64-linux-gnu/liblo.so.7.3.0
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'lo_send': /usr/lib/x86_64-linux-gnu/liblo.so.7.3.0: undefined symbol: lo_send
    at com.sun.jna.Function.<init>(Function.java:245)
    at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:566)
    at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:542)
    at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:528)
    at com.sun.jna.Library$Handler.invoke(Library.java:228)
    at com.sun.proxy.$Proxy0.lo_send(Unknown Source)
    at nl.ronaldteune.coverdownloader.Main.main(Main.java:30)

Otras preguntas sobre UnsatisfiedLinkError apuntan a problemas más exhaustivos. No puedo encontrar 'lo_send' al abrir la biblioteca con vim, aunque puedo encontrar lo_send_message, pero es de nivel más bajo. Sin embargo, creo que mi programa C está usando la misma lib (compilada con -llo) y no tiene problemas para ejecutarse. Entonces ... estoy atascado. Alguien sabe cómo puedo depurar más?

Respuesta 1

No puede asignar lo_send()a JNA (y no aparece en su vimsalida) porque es una macro:

#define lo_send(targ, path, types...) \
        lo_send_internal(targ, __FILE__, __LINE__, path, types, \
             LO_MARKER_A, LO_MARKER_B)

Podría, en teoría, mapear, lo_send_internal()pero los comentarios del código fuente dicen:

/* Don't call lo_send_internal directly, use lo_send, a macro wrapping this
 * function with appropriate values for file and line */

Lo cual tiene sentido ya que necesita conocer el código fuente __FILE__y el __LINE__número en el momento de la compilación, y cualquier pirateo que realice en JNA para estos valores debería suponer que tiene el código fuente correcto utilizado para compilar su binario .so. También necesitaría los marcadores, pero son al menos constantes, palabras divertidas enunciadas en código hexadecimal.

Probablemente podría simplemente agregar valores ficticios para el archivo y la línea para que su código funcione, pero de lo contrario, su llamada a la función de contenedor C lo_send()parece la mejor solución en este caso.

Respuesta: 2

Estoy tratando de codificar un programa, que lee una imagen en una imagen almacenada, la pinta en el JFrame, pinta círculos en ella y la escribe en un archivo. El siguiente código lo hará todo excepto el contenido ...

Tengo una clase que tiene una referencia estática al ApplicationContext de Spring. Necesito borrar ese contexto y ejecutar el método de destrucción de sus beans únicos cuando la clase está a punto de descargarse. Asi es ...

Así que esta es la primera vez que publico aquí, así que espero que puedan ayudarme, de todos modos aquí está mi código: System.out.println ("¿Desea ejecutar? (Ingrese y para ejecutar):"); Scanner scan = ...

Creé una aplicación Spring Boot 2.1.3 con i18n habilitado, agregué devtools e instalé la extensión Firefox LiveReload. Desafortunadamente, cuando cambio mis plantillas Thymeleaf o los mensajes i18n, ...