JNA

2010-11-04 15 views
9

ben JNA ile Java dan aramaya çalışıyorum C bir işlevi var olan * bir boşluğa parametreyi bir Java sınıfı geçme: JNA documentation göreJNA

int myCfunc(void *s, int *ls); 

boşluk * Bir com.sun.jna.Pointer olmak gerektirir işleve geçti.

gibi: işaretçi ile bağlantılı ve JNA Yapısı uygulayan sınıflar olacak parametre s geçirilen gereken

public interface myWrapper extends Library{ 
    public int myCfunc(Pointer s, IntByReference ls); 
} 

nesneleri: JNA Java ile aşağıdaki gibi yukarıdaki fonksiyon sarılacak inanıyoruz

public class myClass extends Structure{ 
    public int x; 
    public int y; 
    public int z; 
} 

Maalesef, ls parametresi, sınıfın bayt cinsinden uzunluğunu temsil eden bir tamsayıdır. Java'nın bir sizeof işlevi yoktur, bu yüzden fazladan bir karmaşıklık ekler. Yaşadığım diğer önemli sorun, nesnenin içeriklerini doğal belleğe ve geriye doğru şekilde iletiyorum.

benim kod aşağıdaki benzer:

import com.sun.jna.Native; 
import com.sun.jna.Pointer; 
import com.sun.jna.Structure; 
import com.sun.jna.ptr.IntByReference; 

public void foo(){ 
    myWrapper wrapper = (myWrapper) Native.loadLibrary("SomeDllWithLegacyCode", myWrapper.class); 

    myClass myObj = new myClass(); 
    myObj.x = 1; 
    myObj.y = 2; 
    Pointer myPointer = myObj.getPointer(); 

    int size = Native.getNativeSize(myClass.class); 
    IntByReference len = new IntByReference(size); 

    myObj.write(); //is this required to write the values in myObj into the native memory?? 
    wrapper.myCfunc(myPointer, len); 
    myObj.read(); //does this read in the native memory and push the values into myObj?? 

    myPointer.clear(size); //is this required to clear the memory and release the Pointer to the GC?? 
} 

Ben iletilen verileri bir hata alıyorum C işlevi tarafından beklenen daha büyük boyutta olduğunu. Yukarıdaki kod, benzer bir sorunla ilgilenen bir soruya, ancak C# 'da aynı şekilde as provided out in this answer adımlarını izleyen yukarıdaki kodları takip eder. C# 'de çalıştığını denedim ve test ettim.

Soruma benzer another on Stackoverflow, ancak bir sınıf için bir işaretçi yerine bir IntByReference bir Pointer ile ilgilenir. arasında

cevap

6

ilk JNA aşağıdaki hattı gereksiz olduğu anlamına gelmektedir (ve bellek yığını zarar görebilir) olan otomatik başlıbaşına bellek ayırmalarını ile temas eden tüm:

myPointer.clear(size); //is this required to clear the memory and release the Pointer to the GC?? 

sonraki aynı zamanda otomatik olarak anlamına gelir, doğal işaretçi türleri başa

public int myCfunc(Pointer s, IntByReference ls); 
public int myCfunc(myClass s, IntByReference ls); 

ve böylece JNA sizin için myObj.write(); ve read yapacağız: aşağıda her iki çizgiler halinde eşdeğerdir.

aşağıdaki

% 100 doğru olduğunu ama (3 * 4 = 12 verecek ruh hangi; 4 bayt 3 int) myCfunc çağrınızda önce ve sonra len.getValue() log öneririz: tüm Eğer

int size = Native.getNativeSize(myClass.class); 
IntByReference len = new IntByReference(size); 

Bu doğru, o zaman muhtemelen yapınızın prototipinde bir hata var. Benim deneyim

bu modası geçmiş bir C başlık dosyası veya eski bir kütüphaneye çoğunlukla kaynaklanmaktadır:

  • Sen başlık yapı değerlerini int olduğunu bildiren sürüm 2.0 ancak kütüphane v1.0 karşı bağlama kullanmakta olduğunuz Bir bayt yapısını alır
  • Başlık sürüm 2'yi kullanıyorsunuz.

    public void foo(){ 
        myWrapper wrapper = (myWrapper) Native.loadLibrary("SomeDllWithLegacyCode", myWrapper.class); 
    
        myClass myObj = new myClass(); 
        myObj.x = 1; 
        myObj.y = 2; 
    
        int size = Native.getNativeSize(myClass.class); 
        IntByReference len = new IntByReference(size); 
    
        //log len.getValue 
        wrapper.myCfunc(myObj, len); 
        //log len.getValue 
    } 
    

    Ayrıca deneyebilirsiniz: struct değerlerini int vardır ama sonunda iki ints ve bir bayt

alır kütüphane v1.9 karşı bağlama kod aşağıdaki gibi görünmelidir belirtiyor 0 gönüllü azalma hata ayıklama amacıyla örn için Len'in değeri:

IntByReference len = new IntByReference(size-1); 
IntByReference len = new IntByReference(size-2); 
IntByReference len = new IntByReference(size-3); 
//... 
IntByReference len = new IntByReference(size-11); 

Bu wan't ne olmaz ama en azından bu size vermelidir doğru "max len"

İlgili konular