PVOID und Zeigerübergabe



  • Zu erstmal ich hab das Problem jetzt gelöst .... das ist erstmal die gute Nachricht.

    Mein Problem war eigentlich "nur", dass ich die PVOID Variable in ein Long casten wollte. Ich komm mit dem ganzen Zeiger-Zeug (Referenzen, dereferenzierung, *, &...) noch nicht so richtig klar ...

    Die Funktionen werden alle von der Java-VM aufgerufen und daher kommen auch JNIEnv *env, jobject obj. Mit den zwei Variablen ist es möglich mit der Java-Seite zu interagieren.

    Hier auf jeden Fall nochmal die Lösung des Problems:

    FT_HANDLE ConvertJLongToFT_Handle(jlong handle){
        return (FT_HANDLE)((unsigned long) handle);
    }
    
    jlong ConvertFT_HandleToJLong(FT_HANDLE handle){
        return (jlong)handle;
    }
    

    Trotzdem thx.

    Grüße
    Bob



  • BobRodriguez schrieb:

    Mein Problem war eigentlich "nur", dass ich die PVOID Variable in ein Long casten wollte.

    Aufpassen.

    sizeof(PVOID) und sizeof(long) müssen nicht gleich groß sein.
    Dann hast du Informationsverlust beim cast und die Adresse stimmt nicht mehr.



  • das erklärt dann sicherlich die Warnung:

    warning: cast from pointer to integer of different size
    

    Wie löst man das Problem?



  • BobRodriguez schrieb:

    das erklärt dann sicherlich die Warnung:

    warning: cast from pointer to integer of different size
    

    Wie löst man das Problem?

    long durch einen groß genugen Datentyp ersetzen.
    Ich weiß jetzt nicht auswendig ob ptrdiff_t im C Standard enthalten ist. Ansonsten auch mal size_t nehmen. Prinzipiell wäres natürlich ideal, wenn du alles vermeiden könntest und überall void* verwenden könntest.



  • Das Problem dabei ist, dass ich die Adresse wieder zurück ins Java geben muss...



  • BobRodriguez schrieb:

    Das Problem dabei ist, dass ich die Adresse wieder zurück ins Java geben muss...

    Und kannst du dir den Datentyp aussuchen oder bist du auf long limitiert? Wenn du long verwenden musst, dann kannst du Adressen nicht so hin und her geben. Dann musst du eine Art dictionary einführen und nur die Schlüssel an Java übergeben und im C Code anhand des Schlüssels auf die echte Adresse schließen.

    Vermutlich hat die JNI Schnittstelle aber auch groß genuge Datentypen. Auf 64Bit Systemen sind Zeiger idR 64bit breit. IIRC ist long in Java 64bit breit. In C ist long aber idR 32bit breit.



  • Es gibt im JNI einen Typen jlong, der auf einen Java-Long (d.h. 64 Bit) passt. Da es in Java keine Zeigertypen gibt, wird dieser üblicherweise benutzt, um Zeiger auf native Objekte an Java-Code durchzureichen.

    Sobald Java auf eine Plattform portiert wird, auf der Zeiger 128 Bit breit sind, läuft man damit natürlich in Probleme, aber das dürfte noch einige Zeit hin sein, und falls Java dann noch relevant ist, ist davon auszugehen, dass dann Schritte unternommen werden werden, die API-Kompatibilität zu wahren. Es fliegt inzwischen eine Menge solchen Codes herum.



  • jlong und Java-long sind doch aber 64bit signed (siehe hier), die Pointer-Adresse ist doch aber unsigned. Das heißt doch am Ende, dass ich bei 64bit Adressen ebenfalls ein Informationsverlust habe...

    Oder hab ich hier einen Denkfehler?

    Grüße
    Bob



  • Ganz was anderes:

    JNIEXPORT jlong JNICALL Java_ft232h_Comm_getFirstFT232HDevice (JNIEnv *env, jobject obj){
    
        FT_STATUS ftStatus;
        FT_DEVICE_LIST_INFO_NODE *devInfo;
        DWORD numDevs;
    
        ftStatus = FT_CreateDeviceInfoList(&numDevs);
    
        if(ftStatus != FT_OK)
            return 0;
    
        devInfo = malloc(numDevs * sizeof(FT_DEVICE_LIST_INFO_NODE));
        /* Ethon: Du prüfst nicht ob malloc null zurückgibt */
        ftStatus = FT_GetDeviceInfoList(devInfo,&numDevs);
    
        FT_HANDLE ft232H_Handle = 0;
    
        int tmp = 0;
        while(tmp < numDevs){
            if(devInfo[tmp].ID == 0x4036014){
                ftStatus = FT_Open(tmp, &ft232H_Handle);
                if(ftStatus != FT_OK){
                    printf("could not open FT232H\n");
                    /* Ethon: Hier leakst du Speicher, nämlich devInfo */
                    return 0;
                }
            }
            tmp++;
        }
    
        free(devInfo);
    
        return ft232H_Handle;
    }
    

    jlong und Java-long sind doch aber 64bit signed (siehe hier), die Pointer-Adresse ist doch aber unsigned. Das heißt doch am Ende, dass ich bei 64bit Adressen ebenfalls ein Informationsverlust habe...

    Oder hab ich hier einen Denkfehler?

    Nein, du hast keinen Informationsverlust solange du den Integer genau so nutzt, wie du ihn reingesteckt hast.
    Dass der signed integer "nur" 63 Nutzbits hat wäre sowieso egal, da afaik die meisten CPUs sowieso nicht so hoch addressieren können, zb mein AMD Phenom nutzt auch nur 48bit.



  • Danke für den Hinweis ... Habs gleich geändert.


Anmelden zum Antworten