Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

NicoWe

Treue Seele

  • »NicoWe« ist der Autor dieses Themas

Beiträge: 126

Wohnort: Bielefeld / NRW

  • Private Nachricht senden

1

17.12.2008, 19:16

Linkerfehler in normaler Klassendeklaration

Hallo Leute
Ich hab ein Problem, und zwar wollte ich mir eine Logfileklasse schreiben. Sie ist von Heikos Singleton(leicht abgeändet) abgeleitet. Ich habe eine .cpp, die einen Header includiert, der wiederrum den Header mit der Deklaration includiert. Die Funktionsrümpfe sind in einer Separaten .cpp, die den Header mit den Deklarationen includiert. Wenn ich jetzt eine Funktion aufrufen will, bekomme ich folgenden Linkerfehler:

Quellcode

1
1>Main.obj : error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""public: void __cdecl CLogfile::Info(char *,...)" (?Info@CLogfile@@QAAXPADZZ)" in Funktion ""public: virtual bool __thiscall CMain::Init(void)" (?Init@CMain@@UAE_NXZ)".


Main.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once

//////////////////////////////////

// Includes + defines

#include <d3d9.h>
#include "Logfile.h"
#include "GameShell.h"
#define g_pMain CMain::Get()

class CMain : public CBaseMain, public TSingleton<CMain>
{
private:
    PDIRECT3D9  m_pD3D;                     // Schnitstelle


    bool        InitD3D();                  // DirectX initialisieren

public:
    bool        Init();                     // Initialisieren

    void        Exit();                     // Herunterfahren

    bool        Render(float fTime);        // Zeichnen

    bool        Move(float fTime);          // Updaten

};


Ausschnitt aus Main.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
#include "Main.h"

bool CMain::Init()
{
    CLogfile::New();
    g_pLog->Info("Initialisiere Direct3D");
    if(!InitD3D())
        return false;
    return true;
}


Logfile.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#pragma once

#include <fstream>
#include <iostream>
#include "Main.h"
#include "Singleton.h"
#define LOGFILE_OUTPUT "Logfile.html"
#define g_pLog CLogfile::Get()

class CLogfile : public TSingleton<CLogfile>
{
private:
    void            Init();
    void            Exit();
public:
    inline  void    Error(char* format, ...);
    inline  void    Info(char* format, ...);
    inline  void    Warning(char* format, ...);
    
    CLogfile();
    ~CLogfile();
};


Logfile.cpp

C-/C++-Quelltext

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "Main.h"

CLogfile::CLogfile()
{
    Init();
}

CLogfile::~CLogfile()
{
    Exit();
}

void CLogfile::Init()
{
    std::string buf="<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\"http://www.w3.org/TR/html4/strict.dtd\">\n<html><head><title>Logfile</title></head><body>\n";
    std::fstream output(LOGFILE_OUTPUT, std::ios::out | std::ios::trunc);
    output.write(buf.c_str(), buf.length());
    output.close();
}

void CLogfile::Exit()
{
    std::string tempstr="</body></html>";
    std::fstream output(LOGFILE_OUTPUT, std::ios::out | std::ios::app);
    output.write(tempstr.c_str(), tempstr.length());
    output.close();
}

inline void CLogfile::Error(char* format, ...)
{
    va_list pArg;
    char* buf=new char[512];
    va_start(pArg, format);
    vsprintf_s(buf, 512, format, pArg);
    va_end(pArg);
    std::string tempstr="<p style=\"color:red\">";
    tempstr.append(buf);
    tempstr.append("</p><break />\n");
    std::fstream output(LOGFILE_OUTPUT, std::ios::out | std::ios::app);
    output.write(tempstr.c_str(), tempstr.length());
    output.close();
}

inline void CLogfile::Info(char* format, ...)
{
    va_list pArg;
    char* buf=new char[512];
    va_start(pArg, format);
    vsprintf_s(buf, 512, format, pArg);
    va_end(pArg);
    std::string tempstr="<p style=\"color:green\">";
    tempstr.append(buf);
    tempstr.append("</p><break />\n");
    std::fstream output(LOGFILE_OUTPUT, std::ios::out | std::ios::app);
    output.write(tempstr.c_str(), tempstr.length());
    output.close();
}

inline void CLogfile::Warning(char* format, ...)
{
    va_list pArg;
    char* buf=new char[512];
    va_start(pArg, format);
    vsprintf_s(buf, 512, format, pArg);
    va_end(pArg);
    std::string tempstr="<p style=\"color:orange\"><break />\n";
    tempstr.append(buf);
    tempstr.append("</p><break />\n");
    std::fstream output(LOGFILE_OUTPUT, std::ios::out | std::ios::app);
    output.write(tempstr.c_str(), tempstr.length());
    output.close();
}


Danke für jede Hilfe, wer will darf das Logfile in seinem Projekt benutzen, wenns denn funktioniert
Erfolg ist die Fähigkeit, von einem Misserfolg zum anderen zu gehen,
ohne seine Begeisterung zu verlieren.
-Winston Churchill-

2

17.12.2008, 19:23

C-/C++-Quelltext

1
#define g_pLog CLogfile::Get() 

*Nase rümpf* :?
fka tm

NicoWe

Treue Seele

  • »NicoWe« ist der Autor dieses Themas

Beiträge: 126

Wohnort: Bielefeld / NRW

  • Private Nachricht senden

3

17.12.2008, 19:25

Können wir die diskussionen über den Codestil etwas nach hinten verschieben? mir ist es wichtiger dass es läuft, als dass es in einem guten codestil geschrieben ist ;)
Erfolg ist die Fähigkeit, von einem Misserfolg zum anderen zu gehen,
ohne seine Begeisterung zu verlieren.
-Winston Churchill-

4

17.12.2008, 19:28

Dein Stil ist mir sowas von egal!
Aber da in der Gegend wird imho wohl irgendwo dein Problem liegen...
fka tm

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

5

17.12.2008, 19:41

Du bist sicher, dass Get richtig implementiert ist?

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

17.12.2008, 20:01

Herrje, die inlines sind bei Error, Info und Warnung zu viel...
@D13_Dreinig

Das Gurke

Community-Fossil

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

7

18.12.2008, 11:48

Und auch sonst könnte man nur hoffen, dass der Compiler diese Blöcke nicht inlined ... inline ist für wirklich kleine Blöcke gedacht, die an wenigen Stellen häufig aufgerufen werden.

Bei Logs ist vermutlich eher das Gegenteil der Fall: Die werden von vielen Stellen in der Regel nur einmal aufgerufen.

NicoWe

Treue Seele

  • »NicoWe« ist der Autor dieses Themas

Beiträge: 126

Wohnort: Bielefeld / NRW

  • Private Nachricht senden

8

18.12.2008, 13:58

Ihr habt recht, es geht danke :D

Aber der Compiler entscheidet doch ob inline oder nicht, ich verstehe das jetzt so, dass wenn er dagegen ist er Linkerfehler hervorruft...
aber wieso sagt er denn nicht einfach 'inline not accepted' oder so und nicht 'unresolved external'
Erfolg ist die Fähigkeit, von einem Misserfolg zum anderen zu gehen,
ohne seine Begeisterung zu verlieren.
-Winston Churchill-

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

9

18.12.2008, 14:52

Zitat von »"NicoWe"«

Ihr habt recht, es geht danke :D

Aber der Compiler entscheidet doch ob inline oder nicht, ich verstehe das jetzt so, dass wenn er dagegen ist er Linkerfehler hervorruft...
aber wieso sagt er denn nicht einfach 'inline not accepted' oder so und nicht 'unresolved external'


Nein, das hast du falsch verstanden. Der Compiler kann zwar entscheiden ob er eine Funktion inlined oder nicht, aber egal wie er sich entscheiden; In beiden Fällen wird das Programm erfolgreich compiliert werden.

Zitat von »"Das Gurke"«

Und auch sonst könnte man nur hoffen, dass der Compiler diese Blöcke nicht inlined ... inline ist für wirklich kleine Blöcke gedacht, die an wenigen Stellen häufig aufgerufen werden.

Bei Logs ist vermutlich eher das Gegenteil der Fall: Die werden von vielen Stellen in der Regel nur einmal aufgerufen.


Kanner ja ja garnicht, wird ja nicht mal compiliert. ;P
@D13_Dreinig

Werbeanzeige