[erledigt]Struct per Referenz an Funktion übergeben, übernimmt aber keine Werte aus der Funktion



  • Hallo c-community,

    ich habe folgendes Problem:
    ich habe mir eine Struktur erstellt:

    typedef struct
    {
    	int iID;
    	int iSerialNumber;
    	int iCameraHandle;
    	int iForceFormat;
    	int iIO;
    	int iBuffers;
    	int iRequestStop;
    	char caDeviceName[256];
    	tds_obj_buffer* PictureBuffer;
    	pthread_t ptCameraThread;
    }tds_obj_camera;
    

    Die zugehörige Variable erzeuge ich in meiner main-Funktion:

    tds_obj_camera* OBJ_Camera;
    	CAMERA_Create(OBJ_Camera, 0, 1, "/dev/video0");
    

    Als Ergänzung kurz die Create-Funktion:

    void	CAMERA_Create(tds_obj_camera* This, int ID, int SerialNumber, char* DeviceName)
    {
    	/*	Speicher für tds_obj_camera allokieren	*/
    	if (NULL == (This = malloc(sizeof(tds_obj_camera)))) CAMERA_errno_exit("Allocation of tds_obj_camera failed\tobj_camera.c line 6");
    	/*	Variablen initialisieren	*/
    	CAMERA_Set_ID(This, ID);
    	CAMERA_Set_SerialNumber(This, SerialNumber);
    	CAMERA_Set_CameraHandle(This, -1);
    	CAMERA_Set_ForceFormat(This, 1);
    	CAMERA_Set_IO(This, IO_METHOD_MMAP);
    	CAMERA_Set_Buffers(This, 5);
    	CAMERA_Set_RequestStop(This, 0);
    	CAMERA_Set_DeviceName(This, DeviceName);
    	pthread_create(&This->ptCameraThread, NULL, CAMERA_ThreadFunction, (void*)This);
    }
    

    und eine der Set-Funktionen (hier CAMERA_Set_ID):

    void	CAMERA_Set_ID(tds_obj_camera* This, int ID)
    {
    	This->iID = ID;
    }
    

    Mein Problem ergibt sich aus der Auswertung mit dem Debugger nach der die Variable anscheinend immer (mehrere Zeitpunkte des Erstellungsprozesses überprüft) wie folgt aussieht:

    *OBJ_Camera
    iID                           = 726385537
    iSerialNumber                 = -326959104
    iCameraHandle                 = 611093276
    iForceFormate                 = 280726832
    ...
    ptCameraThread                = 1835098975
    

    Die Set-Funktionen scheinen keinen Einfluss auf die Werte des Structes zu haben, obwohl sie als Zeiger übergeben wurde. Was mache ich an der Stelle falsch?

    MfG
    mirrowwinger



  • Deine Set-Funktion ist richtig, aber die Create-Funktion ist Murks, weil This per Wert übergeben wird.
    ➡

    void    CAMERA_Create(tds_obj_camera** This, int ID, int SerialNumber, char* DeviceName)
    {
        /*  Speicher für tds_obj_camera allokieren  */
        if (NULL == (*This = malloc(sizeof(tds_obj_camera)))) CAMERA_errno_exit("Allocation of tds_obj_camera failed\tobj_camera.c line 6");
        /*  Variablen initialisieren    */
        CAMERA_Set_ID(*This, ID);
    ...
    
    tds_obj_camera* OBJ_Camera;
        CAMERA_Create(&OBJ_Camera, 0, 1, "/dev/video0");
    


  • Dann sollten aber die Set_Funktionen auch die Referenz bekommen oder?

    neue Set-Funktion (hier wieder anhand der Set_ID-Funktion)

    void    CAMERA_Set_ID(tds_obj_camera** This, int ID)
    {
        *This->iID = ID;
    }
    

    [Edit1] Nach ändern des Quellcodes für CAMERA_Create erhalte ich folgende Warnung "Warnung: Übergabe des Arguments 1 von »CAMERA_Create« von inkompatiblem Zeigertyp [standardmäßig aktiviert]" Es scheint hier sollte es einen besseren Weg ohne incompatible Zeiger geben.[/Edit1]



  • mirrowwinger schrieb:

    Dann sollten aber die Set_Funktionen auch die Referenz bekommen oder?

    Nein, die Set-Funktion ist richtig.

    neue Set-Funktion (hier wieder anhand der Set_ID-Funktion)

    void    CAMERA_Set_ID(tds_obj_camera** This, int ID)
    {
        *This->iID = ID;
    }
    

    Das dürfte nichtmal durch den Compiler gehen. ( (*This)->iID ... wäre es)

    [Edit1] Nach ändern des Quellcodes für CAMERA_Create erhalte ich folgende Warnung "Warnung: Übergabe des Arguments 1 von »CAMERA_Create« von inkompatiblem Zeigertyp [standardmäßig aktiviert]" Es scheint hier sollte es einen besseren Weg ohne incompatible Zeiger geben.[/Edit1]

    Den geänderten Aufruf von create hatte ich auch angegeben. Wenn man nur die Schnittstelle, aber nicht den Aufruf ändert, bekommt man natürlich solche Warnungen (C ist leider zu tolerant gegenüber Typfehlern bei verschiedenen Zeigertypen, sonst wär das nicht nur eine Warnung).

    Mach dir bitte klar, dass hier nicht irgendein mystisches "Call-by-reference" stattfindet, sondern dass hier Zeiger -- also ganz normale Objekte, deren Bedeutung darin liegt, dass auf andere Objekte zeigen -- erzeugt und per Wert durch die Gegend geschoben werden. Wenn du sowas hier machst:

    void create(camera* p) {
      p = ...
    }
    

    dann ist das dasselbe wie

    void bla(int x) {
      x = ...
    }
    

    ... wegen der Wertübergabe hat die Zuweisung in der Funktion nach außen hin keinen Effekt.



  • Danke Bashar, mit einem Cast für die Funktion CAMERA_Create funktioniert erstmal alles wunderbar. 2-3 andere Probleme im Verlauf des Programmes konnte ich mit den Hinweisen ebenfalls lösen.

    Endgültige funktionierender Quellcode:

    //Funktion
    void	CAMERA_Create(tds_obj_camera** This, int ID, int SerialNumber, char* DeviceName)
    //Aufruf im Main-Funktion mit Cast
    CAMERA_Create((tds_obj_camera**)&OBJ_Camera, 0, 1, "/dev/video0");
    

    Bei mir kompilierbar ohne Warnungen. Aufruf der Set-Funktionen gemäß Bashar.

    MfG
    mirrowwinger



  • mirrowwinger schrieb:

    Danke Bashar, mit einem Cast für die Funktion CAMERA_Create funktioniert erstmal alles wunderbar.

    Von Cast hab ich nichts gesagt.

    Endgültige funktionierender Quellcode:

    //Funktion
    void	CAMERA_Create(tds_obj_camera** This, int ID, int SerialNumber, char* DeviceName)
    //Aufruf im Main-Funktion mit Cast
    CAMERA_Create((tds_obj_camera**)&OBJ_Camera, 0, 1, "/dev/video0");
    

    Bei mir kompilierbar ohne Warnungen. Aufruf der Set-Funktionen gemäß Bashar.

    Falls OBJ_Camera noch wie im ersten Posting als Zeiger auf tds_obj_camera deklariert ist, dann hat &OBJ_Camera bereits den Typ tds_obj_camera**, der Cast ist somit nutzlos. Falls nicht -- dann unterdrückt der Cast Warnungen oder Fehlermeldungen. Lass ihn also am besten weg


Anmelden zum Antworten