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

Faule Socke

Community-Fossil

  • »Faule Socke« ist der Autor dieses Themas

Beiträge: 1 915

Wohnort: Schreibtischstuhl

  • Private Nachricht senden

11

08.06.2007, 16:14

Zitat von »"David_pb"«

Ich weiß das es nicht geht! Probiers doch selbst aus! ;-) Templatecode muss von einer Compiliereinheit sichtbar sein. Das ist gewährleistet wenn der Code in einer Datei steht oder exportiert wird (Templateexport, was aber kaum ein Compiler unterstützt).
Ich vermute also schwer das irgendwo ein Fehler passiert den du nicht siehst oder sonstwas...


Also folgendes: Die Dll lässt sich Problemlos kompilieren!
2. Sie benutzt intern die Stringklasse und das nciht selten.
3. Wenn ich ein Projekt erstelle, welches die Dll Verwendet(und die Stringklasse) lässt sich dass auch kompiliren.
4. Wenn ich dieses Projekt dann starte, funktioniert es auch und stürtzt NICHT ab!

5. Ich kann die Stringklasse sogar debuggen(was ich auch machen musste, als ich sie erstellt habe, da sie noch buggy war)

Was soll ich sagen... ich weis auch net wie ich es geschafft habe, da es ja laut dir unmöglich ist aber es geht! Willste nen Screenshot oder sowas?


mfg,

Faule Socke

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

12

08.06.2007, 16:27

Keine Ahnung was da falsch läuft. Aber schon Templatecode in die DLL zu exportieren ist schlichtweg unsinnig, da der Code der Klasse erst bei konkreter Verwendung erzeugt und kompiliert wird kann er nicht vorkompiliert werden.

Du hast übrigens ein Memoryleak in der Stringklasse. Abgesehen von den anderen Fehlerchen! ;-P
@D13_Dreinig

Faule Socke

Community-Fossil

  • »Faule Socke« ist der Autor dieses Themas

Beiträge: 1 915

Wohnort: Schreibtischstuhl

  • Private Nachricht senden

13

08.06.2007, 21:04

Zitat von »"David_pb"«

Du hast übrigens ein Memoryleak in der Stringklasse. Abgesehen von den anderen Fehlerchen! ;-P


Sie ist ja auch noch net fertig(eher so ne eilige vorabversion, weil ich einfach mal eine version rausbringen musste... schwer zu erklären)

Wo ist denn das Leak? Und welche anderen kleinen fehlerchen?


mfg,

Faule Socke

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

14

08.06.2007, 21:32

Zitat von »"Faule Socke"«


3. Wenn ich ein Projekt erstelle, welches die Dll Verwendet(und die Stringklasse) lässt sich dass auch kompiliren.


wenn du das machst, dann musst du aber in diesem projekt die .h und .cpp dateien der stringklasse einbinden!?

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

15

08.06.2007, 21:56

Zitat von »"Faule Socke"«


Wo ist denn das Leak? Und welche anderen kleinen fehlerchen?


mfg,

Faule Socke


Das Leck befindet sich u.A. im Copy C'tor. Fehlerchen gibts viele. Einige Beispiele:

FastStream.cpp

C-/C++-Quelltext

1
2
3
4
5
// Die Schnittstelle erzeugen

pDevice =   new IFastStreamDevice;

if(!pDevice)
    return 0;


Was ist falsch?
Seit der Operator new nie einen Nullpointer liefert (das war mal früher so) ist diese Abfrage total sinn- und zwecklos. Der Operator new wirfst eine Exception vom Typ std::bad_alloc wenn der Speicher nicht reserviert werden konnte.

Lösung:

C-/C++-Quelltext

1
2
3
4
pDevice = new ( std::nothrow ) IFastStreamDevice;

if ( !pDevice )
  return 0;


fsBuffer.h

C-/C++-Quelltext

1
template<typename T>class FASTSTREAM_API CBuffer : public CString


Was ist falsch?
Da CString ein Klassentemplate ist muss zwangsläufig ein Typ angegeben werden, es sei denn irgendwo wird CString als vollständige Klasse definiert oder Typendefiniert. Aber CString ist ja sowiso mysteriös.

Lösung:
Typ angeben.

Überall wo Templates Exportiert werden

C-/C++-Quelltext

1
template< typename T > class FASTSTREAM_API XYZ ...


Was ist falsch?
Templates können nicht in die DLL exportiert werden. Siehe Erklärung oben.

Lösung:
Einfach nicht exportieren und den gesamten Quellcode bereitstellen.

fsFile.h

C-/C++-Quelltext

1
template<typename T> void CloseHandleT(T **pValue)


Was ist falsch?
Nichts direkt, allerdings wäre ein Referenz auf einen Zeiger wesentlich schöner.

Lösung:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
template< typename T > void CloseHandleT( T*& pValue )
{
        if(!(pValue))
            return;

        ::CloseHandle(pValue);
        (pValue) = NULL;
}


Nahezu überall

C-/C++-Quelltext

1
2
3
4
5
irgendeinzeiger = NULL;

if ( irgendeinzeiger == NULL )

...


Was ist falsch?
Auch nichts direkt, aber ein Zeiger kann in C++ auf '0' getestet werden. NULL ist ein unnötiges Fragment aus C Zeiten und gehört nichtmal zum C++ Standard.

Lösung:
Statt NULL einfach 0 verwenden. Ist mehr C++! ;-)

fsFile.h und überall sonst

C-/C++-Quelltext

1
CFile(char *pcFileName, EFileEncoding Encoding = ANSI);


Was ist falsch?
Die Parameter mit dem Typ char* sollten egtl immer const char* sein.

Lösung:

C-/C++-Quelltext

1
CFile( const char* pcFileName, ... )


An vielen, vielen Stellen

C-/C++-Quelltext

1
foo xyz() { return bar; }


Was ist falsch?
An vielen Stellen hält der Code die const correctness nicht ein.

Lösung:
Const Correctness einfach 100% einhalten. Dann wird evtl auch jemand diese Bibliothek verwenden. Code der sich nicht an die Const Correctness hält landet im Mülleimer.

fsString.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
template<typename T>void CString<T>::InitPtrs()
    {
        // Alle Zeiger auf NULL setzen

        m_pcString      =   NULL;
        m_pcOldString   =   NULL;

        ClearMem();
    }


Was ist falsch?
Memoryleak: ClearMem LÖSCHT beim Aufrufen von InitPtrs Nullpointer. Das macht zwar rein garnichts, aber der Speicher wird dennoch nicht freigegeben.

Lösung:
Erst speicher freigeben, dann Zeiger auf 0 setzen.

fsString.h

C-/C++-Quelltext

1
template<typename T>const void CString<T>::operator += (T *pcText)


Was ist falsch?
Der Operator += hat typischerweise eine vollkommen andere Signatur.

Lösung:

C-/C++-Quelltext

1
2
3
4
5
6
template< typename T >
CString< T >& operator+=( CString& str, T* pcText )
{
  str.AddString( pcText );
  return str;
}


So, um nur einige Fehler und Mängel zu nennen! ;-P
@D13_Dreinig

Das Gurke

Community-Fossil

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

16

09.06.2007, 08:16

Hmm, ob man Zeiger auf '0' oder 'NULL' prüft ist finde ich irgendwie geschmackssache. Ich prüfe bei Pointern immer auf NULL. Dadurch wird, finde ich, der Zweck der Prüfung deutlich klarer. Immer wenn ich im Code so einen NULL Check sehe, weiss ich das ich die "Verfügbarkeit" eines Pointers prüfe. Nur numerische Werte teste ich auf '0'.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

17

09.06.2007, 09:52

Zitat von »"Das Gurke"«

Hmm, ob man Zeiger auf '0' oder 'NULL' prüft ist finde ich irgendwie geschmackssache. Ich prüfe bei Pointern immer auf NULL. Dadurch wird, finde ich, der Zweck der Prüfung deutlich klarer. Immer wenn ich im Code so einen NULL Check sehe, weiss ich das ich die "Verfügbarkeit" eines Pointers prüfe. Nur numerische Werte teste ich auf '0'.


Ob man prüfen sollte hängt von der Situation ab. Einen Zeiger auf 0 zu testen vor dem löschen ist total Sinnfrei. Einen Zeiger auf 0 zu testen, nach dem Aufruf von operator new ist genauso Sinnfrei. Ansonsten kann man gern auf 0 testen wenn es notwendig sein sollte und auch wenn im Code NULL steht testet man auf 0, nicht umsonst wird irgendwo NULL als 0 defininiert.
NULL ist dennoch ein Relikt aus C Zeiten und existiert egtl in C garnicht mehr. Und das Argument, Testen mit NULL sieht mehr nach Zeiger aus, ist irgendwie totaler Schwachsinn.
@D13_Dreinig

Das Gurke

Community-Fossil

Beiträge: 1 996

Wohnort: Pinneberg

Beruf: Schüler

  • Private Nachricht senden

18

09.06.2007, 10:04

Das '0' und 'NULL' aufs gleiche hinauslaufen streite ich ja garnicht ab.

Ich mache nur gerne klar wo ich auf einen numerischen Wert teste und wo ich einen Pointer bzw Speicherbereich überprüfe. Besonders wenn man dann doch mal wieder ausserhalb einer praktischen IDE arbeiten muss und keine Ungarische Notation verwendet, kann das nerviges Suchen in Headerfiles ersparen.

Und alternativ kann man den "direkten" Vergleich ja auch noch weglassen. (Das bezieht sich allerdings nicht direkt auf dich, das du das weisst ist mir klar *g*)

C-/C++-Quelltext

1
2
if(pointer)
    pointer->doSomething();

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

19

09.06.2007, 10:07

Klar kann man die Definition NULL verwenden. Ist halt aber C-Style und hat mit C++ rein garnichts zu tun. Aber wem das gefällt, klar... Zur not kann man NULL ja selbst definieren.
@D13_Dreinig

grek40

Alter Hase

Beiträge: 1 491

Wohnort: Dresden

  • Private Nachricht senden

20

09.06.2007, 22:12

Zitat von »"David_pb"«


fsString.h

C-/C++-Quelltext

1
template<typename T>const void CString<T>::operator += (T *pcText)


Was ist falsch?
Der Operator += hat typischerweise eine vollkommen andere Signatur.

Lösung:

C-/C++-Quelltext

1
2
3
4
5
6
template< typename T >
CString< T >& operator+=( CString& str, T* pcText )
{
  str.AddString( pcText );
  return str;
}



Soweit ich weiß empfielt es sich operator+= im Gegensatz zu operator+ direkt in die Klasse zu implementieren... oder spricht da irgendwas dagegen?

Ich würde operator+= folgend definieren:

C-/C++-Quelltext

1
2
3
4
5
6
template< typename T >
CString< T >& CString< T >::operator+=( const CString<T>& str )
{
  AddString( str );
  return (*this);
}


Hier würden dann die bereitgestellten Konstruktoren entscheidend dafür sein, welche Variablen man zu einem CString dazu zählen kann.

Werbeanzeige