Ik krijg dus de foutfatal error LNK1169: one or more multiply defined symbols found C:\Documents and Settings\Eerste gebruiker\Bureaublad\UHasselt TMP\TMP TMS\TMS Video Compression\Video Compression trunk\Debug\VideoCodec.exe
.
Nu heb ik die natuurlijk al eerder gehad en opgezocht en weet ik dat dat is wat je krijgt als je hetzelfde ding meerdere keren definieert...
Alleen snap ik niet hoe dat nu kan in mijn geval :
- de probleemfile, a.h. Deze bevat 1 functie in een namespace (voor het voorbeeld tenminste).
- main.cpp, waar het programma start en waar ik die functie nodig heb.
- bla.h en bla.cpp waarin ik een class definieer en die gebruikt de functie uit de probleem file ook.
In main.cpp wordt de probleemfile dus geinclude en naar keuze in bla.h of bla.cpp. Beide mogelijkheden resulteren in de genoemde error.
Kennelijk is dit niet de juiste aanpak...
Hoe moet ik nu wel correct iets maken als de STL library, een simpele file die je kan includen met een handvol nuttige functies, afgeschermd in hun eigen namespace? Ik wil die namelijk niet in een speciaal object moeten gaan moffelen en dan allemaal static zitten maken want dat is ook maar overdreven lijkt mij. Plus, als de STL library het kan, waarom ik dan niet?
En dan nu maar even de voorbeeld code :
Wat ik ook al heb geprobeerd is :
met tegelijk
Dan kreeg ik de error
fatal error LNK1120: 1 unresolved externals C:\Documents and Settings\Eerste gebruiker\Mijn documenten\Visual Studio 2005\Projects\Testproject\Debug\Testproj.exe
Als ik in main.cpp blala::func(); in commentaar zet, dan compileert het wel, maar is het vrij nutteloos natuurlijk (tenminste, met de cpp en .h aanpak van hier beneden - met de aanpak van boven met enkel de .h, dan krijg ik dezelfde multiply defined fout).
Het komt er op neer dat als ik't include op 2 plaatsen inclusief functie definitie, dan krijg ik die multiply defines, ongeacht dat er include guards rond staan. Als ik 't opsplits in .h en .cpp file zoals een class (maar het is een namespace, en ik heb dat echt NERGENS zo zien doen in geen enkel voorbeeld), dan mag ik de functie niet gebruiken want dan klaagt hij dat ze niet bestaat.
Ik kan trouwens ook vermelden dat ik heb geprobeerd om het probleem bestand a.cpp te noemen ipv a.h en dat te includen, en dat geeft nog veel gemakkelijker die error... ben de situatie even kwijt, maar komt er op neer dat als je die include ergens dan is het al fout want dan vind hij de definities al in die a.obj en de obj die hij gemaakt heeft van je file waar je het include. Hij is dan blijkbaar in conflict met zichzelf (ligt het nu aan mij of mocht C(++) qua syntax wel wat intelligenter zijn? Zo'n dingen moet je toch automatisch kunnen oplossen zonder te kijken naar bestandsextensies).
Dus de vraag in het kort is : Wat is de correcte aanpak voor een "algemene library" te schrijven met wat losse functies zoals de STL?
En in het concreet, hoe kan je multiply defines fout krijgen zelfs als je files include guards en/of pragma once bevatten?
.
Nu heb ik die natuurlijk al eerder gehad en opgezocht en weet ik dat dat is wat je krijgt als je hetzelfde ding meerdere keren definieert...
Alleen snap ik niet hoe dat nu kan in mijn geval :
- Ik include alleen files met #pragma once (wat Visual Studio zelf genereert) of
C++: filename.ext1 2 3 4
#ifndef FILENAME_EXT #define FILENAME_EXT [i]<code>[/i] #endif
- Alles werkt, zolang ik die header file maar niet include in 2 verschillende cpp files.
- de probleemfile, a.h. Deze bevat 1 functie in een namespace (voor het voorbeeld tenminste).
- main.cpp, waar het programma start en waar ik die functie nodig heb.
- bla.h en bla.cpp waarin ik een class definieer en die gebruikt de functie uit de probleem file ook.
In main.cpp wordt de probleemfile dus geinclude en naar keuze in bla.h of bla.cpp. Beide mogelijkheden resulteren in de genoemde error.
Kennelijk is dit niet de juiste aanpak...
Hoe moet ik nu wel correct iets maken als de STL library, een simpele file die je kan includen met een handvol nuttige functies, afgeschermd in hun eigen namespace? Ik wil die namelijk niet in een speciaal object moeten gaan moffelen en dan allemaal static zitten maken want dat is ook maar overdreven lijkt mij. Plus, als de STL library het kan, waarom ik dan niet?
En dan nu maar even de voorbeeld code :
C++: a.h
1
2
3
4
5
6
7
8
| #ifndef A_H #define A_H namespace blala { void func(){} } #endif |
C++: main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| #include <algorithm> #include <string> #include <iostream> #include <cctype> // for toupper() #include "cube.h" #include "a.h" int main() { std::string s("hello"); // lowercase // transform the string to uppercase std::transform(s.begin(), // original string's beginning s.end(), // original string's end s.begin(), // where to write the new string? toupper); // unary operator std::cout << s; // display "HELLO" /*begin http://www.functionx.com/cpp/examples/simpleclass.htm*/ Cube cube; cube.setSide(-12.55); cube.Properties(); Cube de; de.setSide(28.15); de.Properties(); /*einde http://www.functionx.com/cpp/examples/simpleclass.htm*/ blala::func(); system("pause"); } |
C++: bla.h
1
2
3
4
5
6
7
8
9
| #pragma once #include "a.h" class bla { public: bla(void); public: ~bla(void); }; |
C++: bla.cpp
1
2
3
4
5
6
7
8
9
10
| #include "bla.h" bla::bla(void) { } bla::~bla(void) { } |
Wat ik ook al heb geprobeerd is :
C++: a.h
1
2
3
4
5
6
7
8
| #ifndef A_H #define A_H namespace blala { void func(); } #endif |
met tegelijk
C++: a.cpp
1
2
3
4
5
6
7
8
9
| #include "a.h" #include <iostream> namespace blala { void func() {std::cout<<"functie in namespees"; } } #endif |
Dan kreeg ik de error
fatal error LNK1120: 1 unresolved externals C:\Documents and Settings\Eerste gebruiker\Mijn documenten\Visual Studio 2005\Projects\Testproject\Debug\Testproj.exe
Als ik in main.cpp blala::func(); in commentaar zet, dan compileert het wel, maar is het vrij nutteloos natuurlijk (tenminste, met de cpp en .h aanpak van hier beneden - met de aanpak van boven met enkel de .h, dan krijg ik dezelfde multiply defined fout).
Het komt er op neer dat als ik't include op 2 plaatsen inclusief functie definitie, dan krijg ik die multiply defines, ongeacht dat er include guards rond staan. Als ik 't opsplits in .h en .cpp file zoals een class (maar het is een namespace, en ik heb dat echt NERGENS zo zien doen in geen enkel voorbeeld), dan mag ik de functie niet gebruiken want dan klaagt hij dat ze niet bestaat.
Ik kan trouwens ook vermelden dat ik heb geprobeerd om het probleem bestand a.cpp te noemen ipv a.h en dat te includen, en dat geeft nog veel gemakkelijker die error... ben de situatie even kwijt, maar komt er op neer dat als je die include ergens dan is het al fout want dan vind hij de definities al in die a.obj en de obj die hij gemaakt heeft van je file waar je het include. Hij is dan blijkbaar in conflict met zichzelf (ligt het nu aan mij of mocht C(++) qua syntax wel wat intelligenter zijn? Zo'n dingen moet je toch automatisch kunnen oplossen zonder te kijken naar bestandsextensies).
Dus de vraag in het kort is : Wat is de correcte aanpak voor een "algemene library" te schrijven met wat losse functies zoals de STL?
En in het concreet, hoe kan je multiply defines fout krijgen zelfs als je files include guards en/of pragma once bevatten?
[ Voor 6% gewijzigd door Rygir op 16-08-2009 06:22 . Reden: a.cpp aanpak ook nog even vermelden. ]