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

Gruwe

Frischling

  • »Gruwe« ist der Autor dieses Themas

Beiträge: 6

Wohnort: Saarland

Beruf: Elektroingenieur

  • Private Nachricht senden

1

27.01.2014, 19:20

Problem bei Benutzung von TriBase-Engine in eigenem Projekt

Hallo,

da ich nun nach abgeschlossenem Studium eine neue Herausforderung suche und ich eigentlich immer schon gerne programmiert hab (bisher allerdings immer nur irgendwelche Anwendungen), habe ich mir vor einigen Tagen das Buch von David gekauft und die ersten Seiten gelesen.

Da ich es, um den für mich besten Lerneffekt zu bekommen, so angehen möchte dass ich die Engine soweit es geht nachprogrammiere, habe ich zuerst mal selbst die grundlegenden Sachen programmiert sowie angefangen mit der Vektor3D-Klasse. D.h. ich habe bisher lediglich eine tribase.h/.cpp sowie eine tbVector3.h/.cpp erstellt.
In den tribase-Dateien sind nur das Notwendigste drin (meines Erachtens), also z.B. alle anderen Header-Files der Engine rausgeworfen etc.

Nun habe ich die Engine soweit kompiliert, was soweit auch funktioniert hat. Ich habe eine DLL-Datei sowie eine LIB-Datei erhalten. Da ich noch nie mit DLLs gearbeitet habe, hab ich mir erstmal ein Projekt EngineTest angelegt und in den Projekteinstellungen alles notwendig eingestellt sowie die Header-Datei tribase.h in die EngineTest.h inkludiert. Soweit, so gut! Funktioniert einwandfrei.

Dann habe ich in der Source-Datei tribase.cpp eine leere Main-Funktion erstellt (also nur int main(){ return 0; } ), welche lediglich 0 zurückgibt. Das funktioniert auch einwandfrei, beim Starten geht kurz ein Konsolenfenster auf und wieder zu.

Jetzt zu meinem Problem:

Ich wollte testweise einen 3D-Vektor anlegen und in einen zweiten kopieren. Das Ganze sieht jetzt so aus:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
#include "EngineTest.h"

int main()
{
    tbVector3 vector1(10, 12, 14);
    tbVector3 vector2(vector1);
    return 0;
}


Also wie gesagt noch nicht vieles.
Wenn ich allerdings dieses kompiliere, erhalte ich die Meldung "error LNK1120: Nicht aufgelöste Externe".

Eigentlich sollte alles richtig sein. Ich habe:

- 3 Ordner erstellt (LIB, BIN und INCLUDE) und jeweils die passende Datei reingelegt (gleiche Reihenfolge: tribase.lib, tribase.dll, tribase.h/tbVector3.h)

- Ich benutze Visual Studio 2013 Express. Dort habe ich bei den Projekt-Eigenschaften das Include-Verzeichnis (INCLUDE) und das Library-Verzeichnis(LIB) hinzugefügt.

- Die DLL-Datei zusätzlich in das Verzeichnis der EXE gelegt.

Kann mir jemand helfen und sagen wo das Problem liegen könnte? Danke!

FSA

Community-Fossil

  • Private Nachricht senden

2

27.01.2014, 19:38

Du musst die Klasse vermutlich erstmal in die DLL exportieren. __declspec(dllexport) hilft dabei:

C-/C++-Quelltext

1
2
class __declspec(dllexport) SomeClass
{};

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Gruwe

Frischling

  • »Gruwe« ist der Autor dieses Themas

Beiträge: 6

Wohnort: Saarland

Beruf: Elektroingenieur

  • Private Nachricht senden

3

27.01.2014, 19:46

Hallo,

danke erstmal für den Tipp!

Allerdings habe ich es so gemacht, wie im Buch beschrieben, d.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
23
24
25
26
27
28
29
30
31
#ifdef TRIBASE_EXPORTS
#define TRIBASE_API __declspec(dllexport)
#else
#define TRIBASE_API __declspec(dllimport)
#endif



//Klasse für dreidimensionale Vektoren
class TRIBASE_API tbVector3
{
public:
    float x;    //Vektorkomponente x
    float y;    //Vektorkomponente y
    float z;    //Vektorkomponente z

//###################################################################
//Konstruktoren

    //Standardkonstruktor: keine Aktion, ausser Konstruktion
    tbVector3() {}

    //Kopierkonstruktor: kopiert den angegebenen Vektor
    tbVector3(const tbVector3& v) : x(v.x), y(v.y), z(v.z) {}

    //Konstruktor, der die angegebenen Vektorkomponenten einsetzt
    tbVector3(const float vx,
              const float vy,
              const float vz) : x(vx), y(vy), z(vz) {}

};


So sollte es doch eigentlich richtig sein, oder?

Hierzu habe ich noch eine weitere Frage:

In den mitgelieferten Dateien steht der folgende Abschnitt lediglich in der TriBase.h:

C-/C++-Quelltext

1
2
3
4
5
#ifdef TRIBASE_EXPORTS
#define TRIBASE_API __declspec(dllexport)
#else
#define TRIBASE_API __declspec(dllimport)
#endif


Dieser Abschnitt steht nicht in anderen Header-Dateien (zumindest nicht in der Vector3). Alle anderen Header sind in TriBase.h inkludiert, umgekehrt jedoch nicht. Woher weiss der Compiler (sofern er nicht TriBase.h als erstes verarbeitet), was TRIBASE_API bedeuetet? Ich habe es daher jetzt zusätzlich nocht in der tbVector3 definiert!

Danke!


edit:

Ok, ich habe nun noch "#define TRIBASE_EXPORS" reingeschrieben, nun funktioniert es! Es kam im Buch so rüber, als würde der Compiler das selbst definieren.
Die zweite Frage würd ich dennoch gerne wissen ;)

Danke!

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Gruwe« (27.01.2014, 19:51)


FSA

Community-Fossil

  • Private Nachricht senden

4

27.01.2014, 19:52

Ein #Include musst du dir so vorstellen, dass der komplette Dateiinhalt in die Datei kopiert wird. Also kennt der Präprozessor die Defines schon. Hast du denn auch TRIBASE_EXPORTS definiert?

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Gruwe

Frischling

  • »Gruwe« ist der Autor dieses Themas

Beiträge: 6

Wohnort: Saarland

Beruf: Elektroingenieur

  • Private Nachricht senden

5

27.01.2014, 19:55

Ein #Include musst du dir so vorstellen, dass der komplette Dateiinhalt in die Datei kopiert wird. Also kennt der Präprozessor die Defines schon. Hast du denn auch TRIBASE_EXPORTS definiert?

Das mit dem #Include ist mir soweit bekannt!

Allerdings dachte ich bisher immer, dass irgendeine header-Datei eines Projektes als erstes bearbeitet wird? Ist dem nicht so, also wird immer zuerst die TriBase.h zuerst verarbeitet? Warum ist das so?

Ja, jetzt hab ich es definiert und es funktioniert! Danke nochmals!

patrick246

Treue Seele

Beiträge: 328

Wohnort: nahe Heilbronn/BW

Beruf: TG Profil Informatik-Schüler

  • Private Nachricht senden

6

27.01.2014, 20:52

Es werden nur die .cpp-Dateien verarbeitet. Falls eine .h/.hpp-Datei nirgendwo eingebunden wird, dann wird sie auch nicht kompiliert. Solange die TriBase.h als erstes include da steht wird sie auch als erstes verarbeitet.

Gruwe

Frischling

  • »Gruwe« ist der Autor dieses Themas

Beiträge: 6

Wohnort: Saarland

Beruf: Elektroingenieur

  • Private Nachricht senden

7

28.01.2014, 19:35

Hallo,

ich nochmal!

So langsam beginnen die Probleme. Ich wollte nun zusätzlich mal noch die fertige TriBase-Engine kompilieren, um diese für die ganzen Übungsaufgaben benutzen zu können. Da ich ja eine andere Version (Express 2013), wird ja empfohlen diese entsprechend neu zu kompilieren.

Allerdings scheint es Probleme zu geben mit DirectX9 beim Linken!

Ich habe dann erstmal ein reines Projekt erstellt nur mit DirectX9 drin (benutze das SDK von Jun 2010). Habe alle Einstellungen gemacht, die notwendig sein sollten (Lib/Include-Verzeichnis in den Einstellungen eingestellt und dem Linker die zusätzliche Abhängigkeit d3d9.lib mitgeteilt).

Dann habe ich folgenden Code geschrieben:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <Windows.h>
#include <stdio.h>
#include <d3d9.h>

#pragma comment (lib, "d3d9.lib")

int WINAPI WinMain(HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    char* pcCmdLine,
    int iShowCmd)

{

    PDIRECT3D9 pD3D = Direct3DCreate9(D3D9b_SDK_VERSION);

    pD3D->Release();

    return 0;
}


Das mit dem "#pragma comment..." hab ich wie man sehen kann auch schon versucht. Dennoch gibt es Linker-Probleme und zwar:

Fehler 1 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "_Direct3DCreate9@4" in Funktion "_WinMain@16". E:\Programmierung\Eigene\DX9Test\DX9Test\DX9Test.obj DX9Test
Fehler 2 error LNK1120: 1 nicht aufgelöste Externe E:\Programmierung\Eigene\DX9Test\Debug\DX9Test.exe DX9Test


Natürlich habe ich die Info-Box im Buch gefunden, dass man in diesem Fall wohl nicht die lib verlinkt hat. Das hab ich jedoch getan und das mehrmals neu.

Unter Projekte->Einstellungen->Linker->Eingabe steht jetzt bei Zusätzlichen Abhängigkeiten "d3d9.lib;%(AdditionDepencies)".

Den Include-Ordner sowie den Lib-Order (auch entsprechend den x64) korrekt ausgewählt.

Hat noch jemand eine Idee, woran es liegen könnte?

Danke!

edit:
Da fällt mir noch ein: Als ich die TriBase-Engine kompilieren wollte, fand er noch z.B. die "asyncio.h" sowie die "asyncrdr.h" auch nicht! Darüber findet man auch kaum was bei Google. Warum sollten diese Dateien bei mir fehlen? Ich glaub am Besten ist es, wenn ich mir von MSDNAA noch schnell mal Visual Studio 2010 runterlade, vielleicht ändert das was an der Sache und es hängt an der Express-Version?

edit2:

Leider auch mit Visual Studio 2010 Ultimate und nach Neuinstallation des DirectX SDK keine Besserung!

Hier noch die Einstellungen als Bild:


(Link)



(Link)



(Link)

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Gruwe« (28.01.2014, 21:59)


Gruwe

Frischling

  • »Gruwe« ist der Autor dieses Themas

Beiträge: 6

Wohnort: Saarland

Beruf: Elektroingenieur

  • Private Nachricht senden

8

30.01.2014, 10:21

Hallo,

ich konnte das Problem mittlerweile lösen.

Für alle die der Meinung sind, alles richtig eingebunden zu haben und dennoch den oder einen ähnlichen Fehler erhalten:

Unbedingt beim Einstellen des LIB-Verzeichnisses darauf achten, dass auch genau das richtige für die Anwendung, die man programmiert eingestellt ist. Also x86 oder x64.

Ich hatte bisher immer mit 32bit-Systemen programmiert und dementsprechend x86 eingestellt (Ich dachte, es hängt damit zusammen, welches System man benutzt).

Ich hatte hier x64 eingestellt, nun mit x86 funktioniert es problemlos, da ich ja eine Win32-Anwendung erstellt habe. So hab ich das zumindest mal wieder hinzu gelernt. Ich werde

jetzt auf jeden Fall mal noch testen, ob nun auch die fehlenden Header, also z.B. asyncio.h gefunden werden.

Werbeanzeige