# Cits ... >  C function call kautkā nestrādā

## Epis

Lieta tāda ka gribu izsaukt C funkciju no cita faila bet nevella nesanāk visu laiku visādi errori populārākais ir : 
 multiple definition of `pogaTest'  
šitas ir pirmais fails; 


```
#include "stm32f10x_lib.h"
#include "Pogas_funkcija.c"
int main(void) 
{
s32 a2,b2,c2;
a2=5; b2=7;
c2=a2+b2;
 pogaTest(c2,a2);
}
```

 šitais otrs Pogas_funkcija.c fails no kurienes tad es izsaucu to funkciju pogaTest(a,b)


```
#include "stm32f10x_lib.h"

extern s32 poga1;
 extern s32 poga2;

void pogaTest(s32 a,s32 b)
{
    s32 poga1= a+b;
    s32   poga2 = a-b;
}
```

 pirmstam ja kas kad rakstīju tajā savā stm32 USB kodā to jauno funkciju es tur neko īpašu nedarīju apmēram tā pat tikai tur viss gāja a te nekas neiet ? (programma ar ko kompilēju ir Ride7 
vispār es tagat meģinu pārtaisīt visual C# kodu uz to parasto C un kautko nekas nesanāk, un dīvaini ir arī ar tiem mainīgajiem visual C# var definēt vai mainīgais ir Private, vai Public, proti ja private tad viņš ir piejams tikai tām vietējām faila funkcijām, bet ja publiskais tad jebkurš ārējais fails var arī viņu ietekmēt, izskatās ka šitajā C nekā tāda nav viss ko atradu ir tas extern un es pagaidām nezinu vai viņš vispār strādā, jo kods ta nekompilējās.

----------


## karloslv

O jā, prijehaļi. Iekļaut .c failus ar #include - tas ir līmenis. Varbūt tomēr vajag vismaz pamatu līmenī apgūt C valodu, pirms tajā sākt muļķības kleķerēt?

A kas nestrādā? Atskaitot to, ka kods ir līks un garantēs vēl daudz nepatikšanu, neredzu jautājumu - ko tu sagaidīji un kas nesanāca? Šo tavu kodu normāls kompilators izoptimizētu līdz 0 instrukcijām, tur arī nekas netiek darīts, skaitļus var saskaitīt, arī nepalaižot programmu.

----------


## Epis

ieliku to savu test kodu iekš tā USB koda kas mangāja un to pogaTest() ieliku iekš hw_config.c faila un pārējo zem main.c un viss aizgāja (vaidzēja noņemt to extern figņu), bet tajā plikajā piemērā nekas neiet ? kas pa lietu ? 

kur slēpjas tas āķis ka tur iet un tur neiet, (jātaisa kautkādi header faili vai ?)

----------


## jeecha

Nee, jaaizlasa kaads tutoriaalis par C/C++, vai arii jaaaiziet uz graamatniicu un jaanopeerk kaada graamata "C dla cainikov". Tu tieshaam sagaidi ka viss forums kolektiivi tev maaciis C/C++ no A liidz Z? Ja jau esi taads gjeenijs un izgudrotaajs, pacenties taksh pats kautko iemaaciities nevis prasiit visiem lai tev ar karotiiti mutee dod.

----------


## Epis

C es zinu jau sen kādu pusotru gadu vai vēl senāk, bet prakstiski tikai kodēju tagat, un tā ir tāda kārtējā specifika kuru grūti atrast goglējot, (pagaidām neko sakarīgu atradis nēsu) 
vienīgā atšķirība ir starp to projektu kas neiet un USB kas iet ir tāda ka tur tam hw_config.c failam ir Heder fails hw_config.h vai tas nozīmē to ka man ir jātaisa pogas_funkcija.h failu ??  un ko tad es tur vispār rakstīšu un definēšu, jo tajā projektā kurš gāja es neko papildus nerakstīju un nedefinēju !  tākā es nerubīju kas pa lietu vels ar ārā ?

----------


## Delfins

muahahha.. gandrīz zem galda....
Zin C jau pusotru gadu un nemāk uztaisīt 2+2 .... doooh... līmenis...

Atver jebkuru grāmatu - tas ir viens no pirmajiem piemēriem par f-ju definīciju.

----------


## Epis

Atradu vainīgo, problēma bīj tajā #include "Pogas_funkcija.c" es šito izkomentēju un tad aizgāja, bet tagat ir jauna problēma nevaru no main faila nolasīt otrā faila mainīgo:
 c2 = poga1; 
kā tur tā lieta īsti darās ?? 
VisualC# varēja tik klāt tiem mainīgajiem ar seciālām darbībām piemēram privātos mainīgos varēja nolasīt ja uztaisīja šādu funkciju:
public double Ypos1Back
        { get { return Ypos1; } } 
un tad jau pašā programmā nolasīja šādā stilla:

Ypos1 = G01Linear.Ypos1Back; 

kā lai to izdara ar C valodu ??  itkā es esu ar extern nodefinējis (extern s32 poga1 ::   un tad vaidzētu visā projektā tikt klāt pie poga1 vērtības   ::

----------


## Epis

Atradu pats, karoči vaidzēja to extern definējumu uztaisīt main.c failā un tajā otrajā failā definē parsti bez nekādiem extern, un cik google palasīju tad to extern tad ir jālieto visos failos caur kuriem grib piekļūt cita faila definētajiem lielumiem.
extern s32 poga1;

----------


## Velko

> Atradu pats, karoči vaidzēja to extern definējumu uztaisīt main.c failā un tajā otrajā failā definē parsti bez nekādiem extern, un cik google palasīju tad to extern tad ir jālieto visos failos caur kuriem grib piekļūt cita faila definētajiem lielumiem.
> extern s32 poga1;


 Nu jau tuvāk patiesībai. Varbūt tagad varēsi aizdomāties arī par šo?



> vai tas nozīmē to ka man ir jātaisa pogas_funkcija.h failu ?? un ko tad es tur vispār rakstīšu un definēšu?


 Pieņemsim - tev ir 10 mainīgie, pie kuriem gribi tikt no 10 citiem failiem. Ko darīsi?

----------


## Epis

> Pieņemsim - tev ir 10 mainīgie, pie kuriem gribi tikt no 10 citiem failiem. Ko darīsi?


 Jāliek tajā .h failā tas extern poga1 definējums ja ? 

es apstījos tajos bibloteku .h failos un šad tad pa retam var atrast kādu mainīgā definējumu ar extern, pārsvarā jau ir #define

----------


## Velko

> Jāliek tajā .h failā tas extern poga1 definējums ja ?


 Bingo!

Pēc tam ar _#include_ pieslēgsi to .h failu kur nepieciešams - nevajadzēs 10x atkārtoties.

Vēl tur liek _typedef_-us, _struct_-us, protams _#define_-s. Iesaku palasīties par funkciju prototipiem - svarīga lieta, un arī to vieta ir .h failos.

----------


## Delfins

Paņem jebkuru open-source C/C++ projektu un paskaties kodu, noformējumu un t.t. Tad viss taps skaidrs, pie kā ir jāpieturās, lai nav problēmas pie izstrādes un turpmākā upgrade procesā, lai nav jāmaldās pa failiem, kuros pats nezin kas rakstīts.

----------


## Epis

Tagat man ir vēlviena problēma proti es uztaisīju to Heder failu un sākumā ierakstīju
#ifndef __CNC_KORDGEN_H
#define __CNC_KORDGEN_H 

un man compileris rāda erroru: /CNC_KordGen.h:3:1: error: unterminated #ifndef 

Es šito nerubīju kļūdu sintaksē nekādu nav, un erors pazūd tikai tad kad noņem to #ifdef, cik lasīju tad to #ifdef vaig lai vien un to pašu Heder failu linkeris neieliktu divreiz, un man tagat sanāk ka strādā tikai tā kā ir viss sliktāk  ::

----------


## Delfins

Tu taču "kodē" C jau pusotru gadu... mjā...



```
#ifndef _AVR_XXX_H_
#define _AVR_XXX_H_ 1

#ifdef _AVR_USE_YYY
    #include "yyy.h"
#endif 

#define XXX_1 0x0001

void func(int *pInt);

#endif /* _AVR_XXX_H_  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
```

----------


## Epis

Pieleca vaidzēja vienkārši pielikt #endif  tagat itkā viss strādā.

----------


## jeecha

Joprojaam uzstaajiigi iesaku kaadu tutoriaali vai graamatu par C/C++ palasiit. Tad nebuus shaadi beernudaarza jautaajumi. Bet diemzheel tas viss laikam ir par tuksho jo pats tu laikam sho teemu maaciities negribi. Tad nu uzrakstiishu nedaudz ceriibaa ka paareejo varbuut tomeer centiisies pats kautkur izlasiit...

Process no C/C++ koda liidz izpildaamam failam notiek shaadi (nu vismaz lielaakajaa daljaa gadiijumu :: :
1) C kompilators veic preproceseeshanu (preprocesora instrukcijas sakaas ar #, piemeeram #include, #ifdef, #define, #if utt utjp).
a) #include darbojas diezgan triviaali - faktiski failaa no kura tu taisi #include tiek iegaazts viss saturs no faila uz kuru #include noraada. Respektiivi ja tev ir aaaa.c kuraa tu taisi #include "aaaa.h", tad preprocesors failaa aaaa.c vietaa kur ir ierakstiits #include "aaaa.h" ieliek visu aaaa.h faila saturu;
b) #define definee macro. Nekaadaa gadiijumaa nevaig jaukt macro ar mainiigajiem, tas NAV viens un tas pats;
c) #ifdef, #ifndef, #if utml paarbauda macro esamiibu un attieciigi izdzeesh vai neizdzeesh kodu kas ir starp #if* un #endif, viens no pielietojumiem ir header failu aizsargaashana pret dubultu #include (tas ko tu mineeji savos piemeeros);
c) ja kautkur kodaa tiek pamaniita atsauce uz macro, tajaa vietaa tiek ielikts tas kas ieksh #define bija uzdefineets, piemeeram ja tu dari #define LABUMINSH  0xFF... tad taalaak kodaa preprocesors aizvietos LABUMINSH ar 0xFF;
1.5) C++ gadiijumaa tiek sintezeets templeitos aprakstiitais;
2) C kompilators kompilee preproceseeto kodu (parasti preproceseeshana un kompileeshana tiek veikta reizee, bet lielaakai daljai kompilatoru ir opcijas kas atljauj veikt tikai preproceseeshanu vai tikai kompileeshanu);
3) linkeris salinko no object failiem kas radaas kompileejot kautko izpildaamu (linkoshana ir atsevishkjsh process, kas nav iisti saistiits ar kompileeshanu).

Ja kompileeshanas/linkoshanas laikaa ir radusies kljuuda - ir ljoti svariigi saprast kuraa no soljiem tas ir noticis. Piemeeram header failu aizsardziiba pret dubultu #include izraisiis nevis linkoshanas kljuudu bet kompilaacijas kljuudu (iznjemot ja tu header failos deklaree nevis funkciju/mainiigo prototipus bet gan pashas funkcijas vai mainiigos, kas protams ir pilniigi "liiki").

Kaadeelj tad vispaar vajadziigi tie .h un .c faili? Tikai taadeelj lai kods buutu paarskataams, modulaars, atkaartoti lietojams un rezultaataa vieglaak uzturams. Tehniski tikpat labi vareetu visu sarakstiit vienaa milziigaa .c failaa...
Kas tad iisti buutu jaaliek .h un kas .c failos:
.h) funkciju prototipi, mainiigo prototipi, dazhaadi konfiguraacijas #define, C++ gadiijumaa klashu deklaraacijas;
.c) funkciju implementaacijas, mainiigo deklaraacijas, C++ gadiijumaa klashu implementaacijas.

----------


## Epis

kautkas palika skaidrāks.

----------

