Potrebbe Java importare classi C ++ da una libreria usando JNA o JNI?

3

In passato, ho usato JNI per accedere ad alcune funzioni winapi, tuttavia winapi è C e quindi solo procedurale. Ora il mio piano è diverso e ho bisogno di sapere se sto andando nella giusta direzione. Quello che voglio è:

  • per creare una libreria C ++ OOP dinamica per Linux (Debian) che, possibilmente basata sulla libreria WiringPi C, consente un approccio object oriented a GPIO di Raspberry PI
  • racchiudi questa libreria nelle classi Java.

Nota che sto anche pensando di usare la libreria nella sua forma originale, ma in alcuni casi dovrò semplicemente aggiungere le funzionalità di WiringPI ai programmi Java esistenti.

Mi sto chiedendo qui perché Google mi ha fallito nel capire se il mio piano è possibile e sano.

    
posta Tomáš Zato 01.09.2015 - 01:50
fonte

2 risposte

4

Il modo consigliato è leggere attentamente la documentazione JNI ufficiale .

(Dichiarazione di non responsabilità: la mia descrizione di seguito potrebbe contenere errori).

Ciò non richiede uno, ma due strati di wrapper (item 2 e 3):

  • Codice applicazione Java
  • Classi di wrapper Java JNI (per fornire un modello di oggetto alla libreria)
  • C wrapper JNI (per il marshalling dei dati tra ambiente JNI e codice C / C ++)
  • Codice libreria C ++

Il wrapper C JNI è responsabile dell'accesso agli array, alle stringhe, ai campi dei membri degli oggetti, ecc. di Java. Ciò è necessario perché Java può spostarsi tra array e oggetti nella memoria, come parte della garbage collection. In un certo senso, il codice C non può accedere a nulla nell'ambiente Java a meno che non ottenga un riferimento (che indica la vita della cosa alla VM). Anche così, si possono ottenere solo gli indirizzi degli array se l'array e il supporto VM si bloccano (essendo appuntati al suo indirizzo di memoria corrente). In caso contrario, ogni accesso ai dati Java richiede la copia e questa copia può essere eseguita solo con l'aiuto di JNI.

La funzione C JNI non può essere una funzione membro della classe, in base alla progettazione. Per poter chiamare le funzioni membro dell'oggetto C ++, il metodo C JNI deve ottenere l'indirizzo dell'oggetto C ++ (in genere archiviato come un campo intero a 32 o 64 bit nella classe wrapper JNI Java) e inserirlo nel C ++ puntatore dell'oggetto.

I maggiori problemi sono:

  • È difficile per i generatori di wrapper generare un modello di oggetto Java soddisfacente dato il codice C / C ++, indipendentemente dal fatto che quest'ultimo sia stato scritto in uno stile OOP. I generatori di wrapper scritti nell'ultimo decennio non comprendono gli stili C / C ++ abbastanza profondi da essere in grado di riconoscere gli idiomi OOP. (La maggior parte potrebbe anche non riuscire ad analizzare il codice C / C ++ legale, a causa della complessità della sintassi del linguaggio.)

  • Un wrapper-scrittore umano farà molti adattamenti di stile tra le due lingue. Fino a poco tempo fa, era difficile imitare tali preferenze (che non sono meccaniche e non dirette) nei generatori di wrapper.

Dai anche un'occhiata

risposta data 05.09.2015 - 23:25
fonte
0

Sì, puoi usare JNI per questo, anche con gli oggetti ... se ha senso è un'altra domanda.

Mettere wiringPi in una propria libreria C ++ mi sembra un po 'strano perché puoi usare la libreria, anche nel codice c ++ e le chiamate al metodo sono davvero semplici. Ecco un tutorial su come usare JNI con c ++: wrapping ac library con JNI

wiringPi è basato su C, in questo modo non vorrei creare una lib di c ++ per l'uso con JNI, basta scrivere un wiringPI-wrapper / adapter per le tue chiamate JNI in C?!

    
risposta data 05.09.2015 - 19:05
fonte

Leggi altre domande sui tag