Skulle behöva lite C hjälp?

Här diskuteras programmering och utveckling
Användarvisningsbild
lennart
Inlägg: 70
Blev medlem: 20 okt 2006, 21:31
OS: Ubuntu
Utgåva: 18.04 Bionic Beaver LTS

Skulle behöva lite C hjälp?

Inlägg av lennart »

Jag har fått en liten skol uppgift att skriva ett c-program som skall göra ett system call (sys_stat) via en funktion som finns i en färdig kompilerad fil. Sys_stat har två argument, char * och struct __old_kernel_stat *, där första argumentet skall vara ett argument ifrån terminalen. Ett av problemen jag har är att få till struct:en, jag bifogar koden jag har skrivit.

Kod: Markera allt

#include <stdio.h>

#include <string.h>


 struct stat {
 };


extern statPrint(char*, struct stat*);


int main(int argc, char *argv[])

{
  int n;
  struct stat *stat;

  /* call statPrint in the libstat.o file */
  n = statPrint(argv[1],stat);
  return 0;

}
Dessutom får jag problem när jag skall länka ihop filerna med kommandot:  gcc -o stat stat.o libstat.o får då följande felmedelande: libstat.o: could not read symbols: File in wrong format
collect2: ld returned 1 exit status
Alla filer ligger i samma katalog, men har egentligen ingen aning hur dom skall ligga och jag utgår ifrån att filen är korrekt.
Hoppas någon vänlig kan hjälpa mig med detta?
Kör Ubuntu 9.10 aplha5, länk till min hårdvara http://www.komplett.se/k/ki.aspx?sku=32 ... roductTabs.
Användarvisningsbild
gasol
Inlägg: 405
Blev medlem: 27 jul 2007, 14:57
Kontakt:

SV: Skulle behöva lite C hjälp?

Inlägg av gasol »

testa å kompilera så här:

om filen heter stat.c

Kod: Markera allt

gcc -c stat.c 
gcc -o stat stat.o libstat.o
Annars så kan du ju testa med detta också

Kod: Markera allt

gcc -o stat stat.c -L./ -lstat
btw är libstat.o kompilerat på en linux-dator eller är det en solaris / BSD binär ?


Sedan så måste du allokera minne för din stat struct eller så har du den på stacken, annars så kommer det bli fel när funktionen försöker läsa den adressen.


edit: eventuellt så kanske det är så att filen är kompilerad till en vanlig x86 processor och du kör en 64-bitars installation?
Senast redigerad av 1 gasol, redigerad totalt 5 gånger.
The Black Mountain Scorpion Hoedown Bluegrass Experience Gang
From Left to Right: Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle.
Användarvisningsbild
lennart
Inlägg: 70
Blev medlem: 20 okt 2006, 21:31
OS: Ubuntu
Utgåva: 18.04 Bionic Beaver LTS

SV: Skulle behöva lite C hjälp?

Inlägg av lennart »

Inget av kommandona funkar. Jag kör en x86:a och jag vet inte om libstat.o är kompilerat på linux eller solaris/bsd, jag visste inte att det var skillnad på dessa binärer, får försöka fråga nästa gång jag får tag på läraren. Skulle dock fortfarande behöva lite hjälp hur man gör med structen, då jag inte är så hemma på språket C. Eller alternativt om någon skulle vilja visa hur man gör ett syscall med stat utan att använda sig av den förkompilerade filen?
Kör Ubuntu 9.10 aplha5, länk till min hårdvara http://www.komplett.se/k/ki.aspx?sku=32 ... roductTabs.
Användarvisningsbild
gasol
Inlägg: 405
Blev medlem: 27 jul 2007, 14:57
Kontakt:

SV: Skulle behöva lite C hjälp?

Inlägg av gasol »

En struct är egentligen en samling av variabler av olika eller samma typ.

Kod: Markera allt

struct namn {
   typ1 namn1;
   typ2 namn2;
   /* osv... */
};

/* t.ex så skulle du kunna representera en 3d - vektor som en struct  */

struct vector3d {
   float x;
   float y;
   float z;
};

/* eller på ett mer kompakt sätt */
struct vector3d {
   float x, y, z;
}


/* Sedan för att komma åt / tilldela ett värde i en struct så gör du såhär: */

/* om man har en pekare till en struct så accessar du värden med -> istället för . */
#define POW2(x) ((x) * (x))
#include <math.h>

int get_length(struct vectord3d *vect) {

   return sqrtf(POW2(vect->x) + POW2(vect->y) + POW2(vect->));

}

int main() {
   struct vector3d vect; /* deklaration */
   int length;

   /* då structen är på stacken så använder du . */
   vect.x = 45.0;
   vect.y = 25.0;
   vect.z = 0.0;

   length = get_length(&vect); /* & tecknet gör att du skickar med adressen till structen */

   return length;
}

edit: har inte kompilerat och testat den här koden jag skrev, så det är möjligt att det finns fel här.
The Black Mountain Scorpion Hoedown Bluegrass Experience Gang
From Left to Right: Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle.
Lars
Inlägg: 6191
Blev medlem: 14 jan 2007, 19:31
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Ort: Stockholm

SV: Skulle behöva lite C hjälp?

Inlägg av Lars »

Du måste på något sätt veta hur structen ser ut, jag är osäker på om den informationen finns o objekt-filen. Har du ingen ytterligare information?

För att kolla objektfilen så kan du använda kommandot file:

Kod: Markera allt

jag@dator:~$ file libstat.o
libstat.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.0, not stripped
Användarvisningsbild
gasol
Inlägg: 405
Blev medlem: 27 jul 2007, 14:57
Kontakt:

SV: Skulle behöva lite C hjälp?

Inlägg av gasol »

Den informationen finns inte kvar i o-filen, adresseringen i en struct är bara offset (ev med padding) från pekaren som beräknas vid kompilering.

Men det borde väl stå i specen till uppgiften
The Black Mountain Scorpion Hoedown Bluegrass Experience Gang
From Left to Right: Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle.
Användarvisningsbild
lennart
Inlägg: 70
Blev medlem: 20 okt 2006, 21:31
OS: Ubuntu
Utgåva: 18.04 Bionic Beaver LTS

SV: Skulle behöva lite C hjälp?

Inlägg av lennart »

Meningen med uppgiften är att man skall lära sig lite om system anrop, därav anledningen till att man får en .o fil, för att man i nästa uppgift skall skriva allt själv. Kan bifoga hur resultatet skall se ut. Har även fått bekräftat att .o filen är kompilerad på en SPARC, då dom inte har linuxburkar på skolan, har bett om en fil till linux. Nedan följer resultatet av en körning.

Kod: Markera allt

[joga@shell ~] $ ./stat /etc/passwd
  File: '/etc/passwd'
  Size: 663271          Blocks: 1312       IO Block: 8192
Device: 0x01540000h     Inode: 24124       Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/     root) Gid: (    1/    other)
Access: 2005-11-09 09:17:46 (2005-11-09 08:17:46 UTC)
Modify: 2005-11-09 09:17:01 (2005-11-09 08:17:01 UTC)
Change: 2005-11-09 09:17:01 (2005-11-09 08:17:01 UTC)
Har börjat skriva på andra uppgiften, eftersom jag inte kunde göra den första, skulle dock behöva lite hjälp med den. Det gäller datumen i ovanstående körning,  dom returneras i structen som antal sekunder efter midnatt 1970. Jag undrar om det finns någon färdig funktion där man kan mata in antal sekunder och få tillbaks korrekt datum i en sträng eller olika heltalsvariabler eller liknande. Hoppas det inte blev för virrigt nu!
Kör Ubuntu 9.10 aplha5, länk till min hårdvara http://www.komplett.se/k/ki.aspx?sku=32 ... roductTabs.
Användarvisningsbild
gasol
Inlägg: 405
Blev medlem: 27 jul 2007, 14:57
Kontakt:

SV: Skulle behöva lite C hjälp?

Inlägg av gasol »

Kolla på funktionerna ctime(), asctime() samt även mktime() testa

Kod: Markera allt

man ctime
För att få upp manualen.
The Black Mountain Scorpion Hoedown Bluegrass Experience Gang
From Left to Right: Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle, Wizard on Bicycle.
Lars
Inlägg: 6191
Blev medlem: 14 jan 2007, 19:31
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Ort: Stockholm

SV: Skulle behöva lite C hjälp?

Inlägg av Lars »

Du kanske också ska köra "man 3 stat" och kika i /usr/include/bits/stat.h efter en struct stat, om det kanske är det du är ute efter.
fyxim
Inlägg: 1
Blev medlem: 10 sep 2007, 17:04

SV: Skulle behöva lite C hjälp?

Inlägg av fyxim »

Känns som någon läser samma kurs.

Kod: Markera allt

#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>

extern statPrint(char*, struct stat*);

int main(int argc, char *argv[])
{
        struct stat buffert;
        stat(argv[1],&buffert);
        statPrint(argv[1],&buffert);
}
Skriv svar

Återgå till "Programmering och webbdesign"