2016-09-22 1 views
0

J'ai un objet de façade pour une DLL que je ne peux pas modifier en utilisant jna. La DLL conserve les états internes et doit toujours être la même instance. L'objet de façade conserve son état. Si je comprends bien, si je change une non-primitive d'un objet, ce changement ne retournera pas à l'appelant puisque le pointeur interne à cette non-primitive pourrait avoir changé.Comment simuler objectpointers

Existe-t-il un meilleur moyen de contourner un wrapperobject pour conserver toutes les modifications? par exemple .:

public class Facade 

{ 
    private final Dll dll; 
    public Facade(int foo, int bar) 
    { 
     //init the Facade 
     this.dll = new Dll(); 
    } 
    int foo(int bar) 
    {} 
    // more methods 
} 

public class Wrapper 
{ 
    public final Facade facade; 

    public Wrapper(Facade facade) 
    { 
     this.facade = facade; 
    } 
} 

public static class App 
{ 
    public static int main(String[] args) 
    { 
     Facade fac = new Facade(0,0); 
     Wrapper pointerSim = new Wrapper(fac); 

     methodA(pointerSim); 
     methodB(pointerSim); 
    } 
} 

Avec l'objectif de pointerSim reflétant les changements après methodA et B aux classes de membres et des tableaux d'octets.

Ou est-ce que mon prétexte est faux?

+0

JNA utilise le mot-clé 'de volatile' pour identifier les champs qui peuvent changer du côté natif (généralement en un autre fil); il évite d'écrire ces champs dans ses méthodes de synchronisation générales ('read()/write()') mais l'écriture peut toujours être effectuée avec 'writeField()'. – technomage

+0

Vous pouvez également utiliser un 'Pointer' générique (ou votre propre' PointerType' afin que vous ayez un certain type de sécurité), et utiliser les méthodes accesseur de mémoire pour pousser/tirer des données seulement si nécessaire. – technomage

+0

@technomage pouvez-vous développer un peu plus s'il vous plaît? – gismo

Répondre

1

Vous pouvez faire circuler des objets natifs en utilisant un simple Pointer. Cette classe a un certain nombre de méthodes d'accès pour lire les offsets en mémoire à partir du pointeur de base.

Si vous voulez taper la sécurité autour d'une classe spécifique de pointeurs, vous pouvez faire votre propre type de pointeur avec

public class Facade extends PointerType { 
    public Facade() { } 
    public Facade(Pointer p) { } 
}