2010-02-11 12 views
7

Ho trovato molti riferimenti online (compresi alcuni su stackoverflow) a JNA utilizzato per le librerie C++, ma non riesco a trovare nulla nei documenti JNA che sia possibile. Non sembra esserci alcun modo per avvolgere una classe C++, in particolare.Java Native Access non fa C++, giusto?

Ho bisogno di accesso nativo per utilizzare RTAudio, ma tutte le funzioni di RTAudio sono funzioni membro della classe RTAudio. Quindi, solo per confermare, JNA non è la strada giusta?

risposta

9

Ciò che questa domanda equivale a chiedere how to call C++ instance methods using JNA, ed è possibile, ma si dovrà fare un po 'di lavoro. In particolare, è necessario scrivere un wrapper con le funzioni extern "C" che è effettivamente necessario richiamare.

Per qualsiasi definizione arbitraria di type* function() è possibile mappare il metodo utilizzando JNA restituendo un valore com.sun.jna.Pointer, ma non sarà possibile richiamare i metodi su un oggetto C++ da JNA.

Una soluzione semplice per questo sarebbe di scrivere una libreria di interfaccia C che invoca semplicemente il metodo sugli oggetti per voi ... quindi se avete qualche funzione membro foo() si potrebbe esportare un metodo di C dal codice C++:

Ovviamente questo aggiungerà un po 'di lavoro per voi ... ma ho il sospetto che il sovraccarico per il passaggio a JNI sarebbe più o meno lo stesso.

JNA si preoccupa solo il modo in cui il metodo viene esportata nella DLL - e che deve essere senza C++ decorazioni (da qui il extern "C"), in modo da poter fare tutto ciò che è necessario all'interno di tale metodo senza esporre metodi che chiami.

Nel mio esempio precedente, questo significa che foo(), a condizione che sia definito all'interno della DLL, non deve essere nemmeno esposto. Poiché è una funzione C++, JNA non può chiamarla direttamente, ma può essere chiamata all'interno di una funzione che JNA può chiamare, ed è per questo che la mia soluzione proposta funziona.

Quindi, sì, è possibile incapsulare completamente le chiamate a tutte le funzioni membro (creare, utilizzare, distruggere) in un'unica funzione e JNA non si preoccuperà.

+0

Grande risposta, grazie.Se un metodo C regolare crea l'istanza della classe C++ all'interno del corpo della funzione, chiama la funzione membro e quindi elimina l'oggetto, è possibile evitare direttamente l'associazione delle funzioni membro? O JNA in qualche modo "sa" e rifiuta ciò che altrimenti sembra essere una funzione C ma che usa il C++ nei loro corpi? –

+1

@carneades: è necessario più spazio di quanto consentito dai commenti, vedere la mia modifica nel post. –

+0

Grazie Mark, ha funzionato perfettamente! extern "C" void rtattempt (void) { RtAudio :: audio RtAudio; std :: cout << "num devices:" << audio.getDeviceCount() << std :: endl; } –

2

Prova Swig. Creerà wrapper per le classi C++ per te.

2

BridJ è un figlio spirituale di JNA che aggiunge un supporto C++ limitato (+ supporto completo da JNAerator). Se non si utilizza anche molti modelli che potrebbe funzionare ...

(disclaimer: io sono l'autore di BridJ & JNAerator)