|
| Header-filer! Fra : Preben Holm |
Dato : 09-03-04 19:55 |
|
Hej alle
Jeg har forsøgt at forstå header-filer og deres funktion og troede
endelig jeg havde set lyset, men nu er solen vist gået ned igen.
Jeg har kigget på linux-kernens header-filer (og jeg indrømmer blankt at
det er noget af et step at tage eftersom jeg knap har lavet Hello World
i C før), men anyway, nu skal jeg bruge alt dette her og er derfor nødt
til at tage en udfordring op.
Så vidt jeg havde forstået skulle der for hver header-fil være en C-fil
som indeholdt de funktioner der var defineret i header-filen, men det
har jeg så også fundet ud af at dette ikke er rigtigt, da jeg har kigget
på linux-kernen... Derimod har jeg også lært at man kan inkludere andre
header-filer i selve header-filen selv, og at disse så kan indeholde de
funktioner jeg leder efter! Men nu er problemet så, at disse filer kan
jeg bare overhovedet ikke finde - er der nogen der har en anvisning
eller f.eks. en forklaring på hvorfor?
Jeg har endvidere set at man kan inkludere header-filen i selve
header-filen selv - hvad har det af betydning?
Altså, hvis vi nu tager f.eks. cpu.h-headeren:
;----------------------------------------------------------------------
#ifndef _ASM_I386_CPU_H_
#define _ASM_I386_CPU_H_
#include <linux/device.h>
#include <linux/cpu.h>
#include <linux/topology.h>
#include <asm/node.h>
struct i386_cpu {
struct cpu cpu;
};
extern struct i386_cpu cpu_devices[NR_CPUS];
static inline int arch_register_cpu(int num){
struct node *parent = NULL;
#ifdef CONFIG_NUMA
parent = &node_devices[cpu_to_node(num)].node;
#endif /* CONFIG_NUMA */
return register_cpu(&cpu_devices[num].cpu, num, parent);
}
#endif /* _ASM_I386_CPU_H_ */
;----------------------------------------------------------------------
og inkluderer altså headerfilen selv. Hvad er meningen med det?
Og spørgsmålet er så endvidere hvor finder jeg funktionen
arch_register_cpu(int num) henne?
På forhånd tak..
Mvh / Preben Holm
| |
Byrial Jensen (09-03-2004)
| Kommentar Fra : Byrial Jensen |
Dato : 09-03-04 21:03 |
|
Preben Holm wrote:
> Jeg har kigget på linux-kernens header-filer (og jeg indrømmer blankt at
> det er noget af et step at tage eftersom jeg knap har lavet Hello World
> i C før),
Ja, det unægteligt en ordentlig mundfuld at starte med Linux-kernen som
er et meget atypisk C-program.
> Så vidt jeg havde forstået skulle der for hver header-fil være en C-fil
> som indeholdt de funktioner der var defineret i header-filen, men det
> har jeg så også fundet ud af at dette ikke er rigtigt, da jeg har kigget
> på linux-kernen...
Sådan er det tit, men det er ikke et krav at det er på den måde.
For at forstå headerfiler, skal man først forstå C's præprocessor. Når
man oversætter et C-program, bliver programmet først behandlet af
præprocessoren[1] som behandler alle præprocessor-direktiverne, som er
de linjer der begynder med "#" herunder #include-direktiverne. Et
#include-direktiv vil indlæse den refererede fil og indsætte indholdet
på direktivets plads[2]. Det betyder at hvis headerfilen indeholder for
eksempel funktionsprototyper, at disse funktionsprototyper vil være
erklærede i den samlede oversættelsesenhed[3] før funktionerne bruges.
[1] I hvert fald idemæssigt. I praksis kan præprocessoren godt være helt
integreret i resten af oversætteren, og forbehandlingen kan godt ske
samtidig med resten af oversættelsen.
[2] Dette gælder ikke nødvendigvis i C++. Her vil #include-direktiver
ikke nødvendigvis referere til en fysisk fil.
[3] En oversættelsesenhed er resultatet af forbehandlingen hvor blandt
andet alle #include-direktiver er udført.
> Derimod har jeg også lært at man kan inkludere andre
> header-filer i selve header-filen selv, og at disse så kan indeholde de
> funktioner jeg leder efter!
Ja, man kan gøre alt i en headerfil som man også kan i selve C-filen,
herunder inkludere andre headere.
> Men nu er problemet så, at disse filer kan
> jeg bare overhovedet ikke finde - er der nogen der har en anvisning
> eller f.eks. en forklaring på hvorfor?
Hvis man bruger direktivet
#include "somefile.h"
skal man lede efter somefile.h samme sted som den fil man aktuelt er ved
behandle. Hvis man derimod bruger formen
#include <somefile.h>
er der tale en systemfil som oversætteren finder på forudbestemte
implementationsafhængige steder. Standardplacering på unix'er (herunder
Linux) er /usr/include/somefile.h. Man kan også ofte give særlige
instruktioner til oversætteren for eksempel på kommandolinjen om
placeringen af sådanne filer når man oversætter.
> Jeg har endvidere set at man kan inkludere header-filen i selve
> header-filen selv - hvad har det af betydning?
Det gør man ikke (i hvert fald ikke ubetinget) fordi det ville give en
uendelig løkke.
> Altså, hvis vi nu tager f.eks. cpu.h-headeren:
> ;----------------------------------------------------------------------
> #ifndef _ASM_I386_CPU_H_
> #define _ASM_I386_CPU_H_
>
> #include <linux/device.h>
> #include <linux/cpu.h>
> #include <linux/topology.h>
>
> #include <asm/node.h>
> [...]
> og inkluderer altså headerfilen selv. Hvad er meningen med det?
Det gør den ikke. Jeg har ikke p.t. installeret Linux-kildeteksten, men
<linux/cpu.h> må referere til en anden fil end du citerer fra. Bemærk at
<linux/cpu.h> skal søges i kataloget "linux" som er på en foruddefineret
plads for systemfiler.
> Og spørgsmålet er så endvidere hvor finder jeg funktionen
> arch_register_cpu(int num) henne?
Den finder du i den headerefil du citerede fra. Lige her:
> static inline int arch_register_cpu(int num){
> struct node *parent = NULL;
>
> #ifdef CONFIG_NUMA
> parent = &node_devices[cpu_to_node(num)].node;
> #endif /* CONFIG_NUMA */
>
> return register_cpu(&cpu_devices[num].cpu, num, parent);
> }
Det er en fuldt definition af funktionen, så den er ikke også andre steder.
| |
Preben Holm (10-03-2004)
| Kommentar Fra : Preben Holm |
Dato : 10-03-04 00:02 |
|
>> Jeg har kigget på linux-kernens header-filer (og jeg indrømmer blankt
>> at det er noget af et step at tage eftersom jeg knap har lavet Hello
>> World i C før),
>
>
> Ja, det unægteligt en ordentlig mundfuld at starte med Linux-kernen som
> er et meget atypisk C-program.
Hvorfor er det et atypisk C-program?
>> Altså, hvis vi nu tager f.eks. cpu.h-headeren:
>> ;----------------------------------------------------------------------
>> #ifndef _ASM_I386_CPU_H_
>> #define _ASM_I386_CPU_H_
>>
>> #include <linux/device.h>
>> #include <linux/cpu.h>
>> #include <linux/topology.h>
>>
>> #include <asm/node.h>
>> [...]
>
>
>> og inkluderer altså headerfilen selv. Hvad er meningen med det?
>
>
> Det gør den ikke. Jeg har ikke p.t. installeret Linux-kildeteksten, men
> <linux/cpu.h> må referere til en anden fil end du citerer fra. Bemærk at
> <linux/cpu.h> skal søges i kataloget "linux" som er på en foruddefineret
> plads for systemfiler.
Ja ok... filen ligger selvfølgelig ikke lige i include-biblioteket, så
det er nok derfor... (bare ifølge min mening ikke så smart at bruge
samme filnavn *gg*)
> Den finder du i den headerefil du citerede fra. Lige her:
>
>> static inline int arch_register_cpu(int num){
>> struct node *parent = NULL;
>>
>> #ifdef CONFIG_NUMA
>> parent = &node_devices[cpu_to_node(num)].node;
>> #endif /* CONFIG_NUMA */
>>
>> return register_cpu(&cpu_devices[num].cpu, num, parent);
>> }
>
>
> Det er en fuldt definition af funktionen, så den er ikke også andre steder.
Ja ok... det er det med at åbne øjnene :)
Takker...
Mvh / Preben
| |
Per Abrahamsen (10-03-2004)
| Kommentar Fra : Per Abrahamsen |
Dato : 10-03-04 09:03 |
|
Preben Holm <64bitNOSPAM@mailme.dk> writes:
> Hvorfor er det et atypisk C-program?
Blandt andet fordi at kernen ikke bruger C standard biblioteket, så
der er en stor del af det vi normalt kalder C der ikke er til
rådighed. Der gør mange ting betydeligt mere komplicerede.
Linux kernens formål er faktisk i høj grad at gøre livet lettere for C
biblioteket, og derved for "almindelige" C programmer.
| |
|
|