Problem mit Unterfunktion



  • Hallo liebe Gemeinde,

    wie der Titel schon sagt habe ich ein Problem mit einer Unterfunktion. Zum Problem... Ich verfüge über zwei c.Datein, eine bezieht aus einem HTTPServer ein Variable welche es an das zweite C-Programm übergeben soll. Leider funktioniert dies nicht wie gewollt, bzw die Unterfunktion tut nicht das was sie soll. Anbei die interessanten Code Ausschnitte:

    #include "dowork.h"
    #include "netutil.h"
    #include <string.h>
    #include <stdio.h>
    #include "Led_Ansteuerung.h"
    
    void dowork(SOCKET clientSocket)
    {
        int ibytes, i, ioffset, iCnt;
        char cbuffer[8192], dateiname[2048];
        const char *httpmsg = "HTTP/1.1 200 OK\nConnection: close\n\n";
        char *pos1, *pos2, *pos3, *pos4, *pos5, *pos6, *pos7, *pos8;
        FILE *datei;
    
        int led[8];
    
        // 6.1. HTTP Kommando empfangen
        ibytes = recv(clientSocket, cbuffer, 4096-1, 0);
        if (ibytes <=0)
        {
    #ifdef _WIN32
            closesocket(clientSocket);
    #else
            close(clientSocket);
    #endif
            return;
        }
    
        // HTTP String terminieren
        cbuffer[ibytes] = '\0';
    
    //    printf("cbuffer=%s\n", cbuffer);
    
        // 6.2. Dateiname aus HTTP-Kommando extrahieren
    
        // GET ?
        if (strncmp(cbuffer, "GET", 3) == 0)
            ioffset = 5;
        else if (strncmp(cbuffer, "POST", 4) == 0)
            ioffset = 6;
        else
            ioffset = 0;
    
        i = 0;
        while (cbuffer[ioffset+i]!= ' ')
        {
            dateiname[i] = cbuffer[ioffset+i];
            i++;
        }
    
        dateiname[i] = '\0';
        printf("Dateiname = %s\n", dateiname);
    
        // Feld led zuruecksetzen
        for (i=0; i<8; i++)
            led[i] = 0;
    
        // POST
        if (ioffset == 6)
        {
            if (strstr(cbuffer, "_LED1_=")) led[0] = 1;
            if (strstr(cbuffer, "_LED2_=")) led[1] = 1;
            if (strstr(cbuffer, "_LED3_=")) led[2] = 1;
            if (strstr(cbuffer, "_LED4_=")) led[3] = 1;
            if (strstr(cbuffer, "_LED5_=")) led[4] = 1;
            if (strstr(cbuffer, "_LED6_=")) led[5] = 1;
            if (strstr(cbuffer, "_LED7_=")) led[6] = 1;
            if (strstr(cbuffer, "_LED8_=")) led[7] = 1;
    
            iCnt = led[0]+led[1]*2+led[2]*4+led[3]*8+led[4]*16+led[5]*32+led[6]*64+led[7]*128;
    
              Led_Ansteuerung(iCnt);
    

    😡

    In der letzten Zeile soll die Funktion Led_Ansteuerung aufgerufen werden, welche keinen Wert zurückgeben soll, jedoch die zuvor errechnete Variabel iCnt benutzen soll. Hier meine Unterfunktion Led_Ansteuerung:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include "ssvpio.h"
    
    void Led_Ansteuerung (int i);
    {
        int fd, inp;
    
        //öffne Treiber, fehlerarbfrage über int fd
        if ((fd= ssvpio_open()) < 0) {
            perror("ssvpio_open");
            exit(1);
        }
    
        // setze DIL/NetPC PIO port A = output, setzt bits in outputmask, setzt bits in inputmask (outputmask hat höhere Priorität)
        ssvpio_write_dir(fd, PORT_A, 0xff,0);
    
        ssvpio_write_dir(fd, PORT_B, 0, 0xff);
    
        //update port A // setze iCnt als setbitmask und resetbitmask
            ssvpio_write_data(fd, PORT_A, i, ~i);
    
            inp = ssvpio_read_data(fd, PORT_B);
    
        return(iCnt);
    

    Sowie die .h Datein zu beiden C- Programmen

    #ifndef DOWORK_H
    #define DOWORK_H
    
    #include "netutil.h"
    
    void dowork(SOCKET clientSocket);
    
    #endif // DOWORK_H
    
    #ifndef Led_Ansteuerung
    #define Led_Ansteuerung
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include "ssvpio.h"
    
    void Led_Ansteuerung(int i)
    
    #endif
    

    😕 Hättet ihr hierzu eine Idee? Vielen Dank für eure Mithilfe im Voraus :p



  • f0xy.- schrieb:

    Leider funktioniert dies nicht wie gewollt,

    Das ist doof.
    Die meisten Regulars hier besitzen zwar eine Glaskugel, nur komischerweise ist die immer gerade verlegt, vollgestaubt oder defekt.
    Daher ist es ein bisschen problematisch heraus zu finden, was nicht funktioniert, was statt dessen passiert und was du erwartest was passieren soll.
    Meine Glasgugel liegt auf der Arbeit. Die Alernative (Hühnerknochen) habe ich leider bei Burger King gelassen.

    Es kann daran liegen, dass du immer wieder ssvpio_open() machst, aber nie das entsprechende close dazu.

    In Led_Ansteuerung-h fehlt ein ;

    Hat Led_Ansteuerung schon mal in einem anderen Programm funktioniert?



  • Da fehlen irgendwie schließende Klammern.



  • DirkB schrieb:

    f0xy.- schrieb:

    Leider funktioniert dies nicht wie gewollt,

    Das ist doof.
    Die meisten Regulars hier besitzen zwar eine Glaskugel, nur komischerweise ist die immer gerade verlegt, vollgestaubt oder defekt.
    Daher ist es ein bisschen problematisch heraus zu finden, was nicht funktioniert, was statt dessen passiert und was du erwartest was passieren soll.
    Meine Glasgugel liegt auf der Arbeit. Die Alernative (Hühnerknochen) habe ich leider bei Burger King gelassen.

    Es kann daran liegen, dass du immer wieder ssvpio_open() machst, aber nie das entsprechende close dazu.

    In Led_Ansteuerung-h fehlt ein ;

    Hat Led_Ansteuerung schon mal in einem anderen Programm funktioniert?

    Also die Funktion Led_Ansteuerung war ursprünglich eine normales C-Hauptprogramm welches ich nun als Funktion nutzen möchte. Diese steuert LED's eines embedded Rechners an, was auch soweit funktioniert hat. Für das ; bin ich schonmal dankbar 😃 Das ist mir entgangen.
    Zur Erklärung des ganzen, ich verfüge wie bereits erwähnt über einen kleinen embedded Rechner mit 8 LED's, welche ich über einen HTTPServer (dowork.c ist Teil hiervon) ansprechen möchte. Auf meiner Website befinden sich Checkboxen, welche in dem Programm dowork.c auf aktivität abgefragt werden. Die Summe der Values der aktiven Checkboxen soll nun in der Variable iCnt gespeichert werden, was soweit auch funktioniert. iCnt, die Summe der Bytes/ Values, soll anschließend in die Funktion Led_Ansteuerung eingelsen werden, welche die Led's letztendlich ansteuert. Hier liegt das Problem nun vergraben. Beim compilen des Servers tritt nun immer ein Fehler in Abhängikeit von Led_Ansteuerung auf. Ich werde morgen/später mal den Fehler posten. Ich denke aber das es sich vielleicht um einen Grundlegenden Verständnisfehler handelt da es sich hierbei um meine erste wirkliche Funktion handelt.



  • f0xy.- schrieb:

    Beim compilen des Servers tritt nun immer ein Fehler in Abhängikeit von Led_Ansteuerung auf.

    WEnn der Fehler beim compilieren auftritt, dann gibt der Compiler auch eine Fehlermeldung.
    Die ist dabei extren hilfreich.

    void Led_Ansteuerung (int i);
    {
    ....
    return(iCnt); //DAS passt nicht zu [c]void [/c]als Rückgabetyp.
    

    Falls du wirklich die Taster einlesen wilst, mach da oben ein int hin.



  • So,

    ich habe eure Fehler mal berichtet und die Fehlermeldungen wurden schonmal weniger 🙂 Zuletzt bleibt folgendes stehen:

    In file included from dowork.c:5:
    ./Led_Ansteuerung.h:10:21: error: expected identifier or '('
    int Led_Ansteuerung(int i);
                        ^
    ./Led_Ansteuerung.h:10:21: error: expected ')'
    ./Led_Ansteuerung.h:10:20: note: to match this '('
    int Led_Ansteuerung(int i);
                       ^
    dowork.c:73:25: warning: expression result unused [-Wunused-value]
            Led_Ansteuerung(iCnt);
                            ^~~~
    1 warning and 2 errors generated.
    make: *** [dowork.o] Error 1
    

    Was mich nun verwirrt ist die geforderte Klammer? Er erwartet eine weitere ( vor int i, sowie eine Abschließende, was jedoch nach meinem Verstädnis nicht erforderlich sein müsste?



  • Vergleiche mal den Include-Guard mit dem Funktionsnamen 😉



  • Ich hoffe ich habe den Hinweis mit dem Include-Guard richtig aufgefasst und habe in meiner Led_Ansteuerung.h ein _H ergänzt.

    #ifndef Led_Ansteuerung_H
    #define Led_Ansteuerung_H
    

    Dies löste zumindest das fehlende Klammerproblem, jedoch kommt nun etwas für mich nun unverständlicheres?

    f0xy$ make
    gcc -o MyHTTPServer main_HTTPServer.o dowork.o netutil.o
    Undefined symbols for architecture x86_64:
      "_Led_Ansteuerung", referenced from:
          _dowork in dowork.o
    ld: symbol(s) not found for architecture x86_64
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    make: *** [MyHTTPServer] Error 1
    

    Ist hiermit der eigentliche Aufruf meiner Funktion in dowork mittels

    Led_Ansteuerung(iCnt);
    

    gemeint? Oder worauf bezieht sich dieser Fehler?



  • Der Linker kann die Funktion Led_Ansteuerung nicht finden.

    Du hast leider nicht die Dateinamen dazu geschrieben.
    Da wo der Code von Led_Ansteuerung steht (Da oben in der zweiten Datei, Zeile 6), gehört hinter void Led_Ansteuerung (int i) kein Semikolon



  • Semikolon wurde entfernt 🙂 Abermals danke hierfür,

    die Datein sind wiefolg benannt:

    1.dowork.c
    2. Led_Test.c
    3.dowork.h
    4.Led_Ansteuerung.h

    Die Reihenfolge entspricht meinem ersten Post. 😕



  • f0xy.- schrieb:

    die Datein sind wiefolg benannt:

    Jetzt ist es egal. es hätte mir die komplizierte Erklärung gespart.

    Ich vermisse Led_Test.c beim Aufruf von gcc (es wird nicht im make-File stehen)



  • Vielen Dank an euch bishierher 🙂 👍
    Ich habe nun die Makefile nun wie folgt geändert.

    MyHTTPServer: main_HTTPServer.o dowork.o netutil.o Led_Test.o
    	gcc -o MyHTTPServer main_HTTPServer.o dowork.o netutil.o Led_Test.o
    
    main_HTTPServer.o: main_HTTPServer.c
    	gcc -c main_HTTPServer.c
    
    dowork.o: dowork.c
    	gcc -c dowork.c
    
    netutil.o: netutil.c
    	gcc -c netutil.c
    
    Led_Test.o: Led_Test.c
    	gcc -c Led_Test.c
    

    Hinzu kommt die make.sh

    #!/bin/bash
    gcc -c main_HTTPServer.c
    gcc -c Led_Test.c
    gcc -c dowork.c
    gcc -c netutil.c
    gcc -o MyHTTPServer main_HTTPServer.o dowork.o netutil.o
    

    Auf meinem embedded kommt nun folgende Fehlermeldung beim ausführen der make.sh, wobei hingegen Lokal ausgeführt sich der Server fehlerfrei starten lässt.

    Led_Test.c:45:2: warning: no newline at end of file
    In file included from dowork.c:5:
    Led_Ansteuerung.h:12:28: warning: no newline at end of file
    netutil.c: In function 'netconnect':
    netutil.c:39: warning: incompatible implicit declaration of built-in function 'memset'
    netutil.c:50: warning: incompatible implicit declaration of built-in function 'memcpy'
    dowork.o: In function `dowork':
    dowork.c:(.text+0x308): undefined reference to `Led_Ansteuerung'
    collect2: ld returned 1 exit status
    

    Was mir nun Kopfschmerzen bereitet ist wie es sein kann, dass ich Lokal gesehen Led_Ansteuerung richtig implementiert habe, auf dem embedded jedoch nicht? 😮



  • f0xy.- schrieb:

    ist wie es sein kann, dass ich Lokal gesehen Led_Ansteuerung richtig implementiert habe,

    Hast du aber nicht.

    Was ist an den Meldungen nicht verständlich?
    Led_Ansteuerung.h:12:28: warning: no newline at end of file
    Du hast die Entertaste nach der letzten } nicht gedrückt.

    netutil.c:39: warning: incompatible implicit declaration of built-in function 'memset'
    netutil.c:50: warning: incompatible implicit declaration of built-in function 'memcpy'

    Die Deklaration (Prototyp) für die beiden Funktionen hat der Compiler aus deinem Code geraten, da du diese (Deklaration) nicht angegeben hast. -> Du hast #include <string.h> vergessen.

    dowork.c:(.text+0x308): undefined reference to `Led_Ansteuerung'
    Der Linker findet Led_Ansteuerung nicht.
    Vergleich mal die Zeilen mit dem -o aus make und make.sh

    Besorg dir ein Buch über C. Lies die Dokumentation zu deinem Compiler.


Log in to reply