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

XP^

Treue Seele

  • »XP^« ist der Autor dieses Themas
  • Private Nachricht senden

21

02.12.2007, 18:58

Omg, jetzt versteh ich nix mehr -.-

Ich hab folgendes versucht:

Die Funktion "Message()" umbenannt, einfach nen "Z" angehängt, sowohl bei header als auch bei CPP(sourcefile).

Nun, ich hab das DLL Projekt kompiliert, dann die tutorial.lib ins andere Projekt verschoben und nun im anderen Projekt die datei kompiliert.

Ausgabe:

Zitat

error C3861: "MessageZ": Bezeichner wurde nicht gefunden.


Also irgendwo hab ich was vergessen, da bin ich mir ziemlich sicher :?

Aber nur was...

MfG

XP^

Treue Seele

  • »XP^« ist der Autor dieses Themas
  • Private Nachricht senden

22

02.12.2007, 22:19

<weiter unten ..>

Nico

Frischling

Beiträge: 82

Wohnort: Nürnberg

  • Private Nachricht senden

23

02.12.2007, 22:49

Zitat von »"David_pb"«

Versuch das:

C-/C++-Quelltext

1
2
3
4
5
6
#pragma once

extern "C"
{
void TUTORIAL_API testmsg(const std::string& any); 
}


@Nico: Es gibt keinen Grund "pragma" grundsätzlich zu vermeiden, ist ja schließlich Standard. Zum Teil bietet diese Funktionalität Vorteile gegenüber alternativen Lösungen an (vgl #pragma once und Includeguards).
Außerdem verwendet er die WinAPI, wieso also nicht die vorteilhafte Alternative wählen?


Du hast mittlerweile echt Spaß daran mich zu flamen was?

Zitat


In the C and C++ programming languages, #pragma once is a non-standard but widely supported preprocessor directive designed to cause the current source file to be included only once in a single compilation. Thus, #pragma once serves the same purpose as include guards, but in less code and without the possibility for name clashes.

http://en.wikipedia.org/wiki/Pragma_once

Es gehört nicht zum Standard. Damit ist es zu vermeiden. Ein einfaches #ifdef, #define, #endif reicht und ist portabler.
Der einzigste Windows-Code den ich hier sehe, ist die WinMain. Und die kann man auch am besten per #ifdef WIN32 bedingt kompilieren.

Genau wie das hier:

Zitat


#ifdef TUTORIAL_EXPORTS
#define TUTORIAL_API __declspec(dllexport)
#else
#define TUTORIAL_API __declspec(dllimport)
#endif

Möchte man das näher an die Portabilität bringen, wäre das hier besser:

C-/C++-Quelltext

1
2
3
4
5
6
7
#if defined(TUTORIAL_EXPORTS) && defined(WIN32)
#define TUTORIAL_API __declspec(dllexport)
#elif defined(WIN32)
#define TUTORIAL_API __declspec(dllimport)
#else 
#define TUTORIAL_API __stdcall
#endif


Und nur als Anmerkung: extern "C" hilft nur bei Linkerproblemen, nicht bei Compilerproblemen. Das Schlüsselwort ist dafür gedacht, den Linker darauf hinzuweisen, dass die Funktion(en) mit der C-Konvention gelinkt wurde und kein C++ Namemangling darauf anzuwenden ist.
http://www.cpp-tutor.de/cpp/le07/le07_03_d1.htm

So, jetzt kannst mich wieder flamen..

XP^

Treue Seele

  • »XP^« ist der Autor dieses Themas
  • Private Nachricht senden

24

02.12.2007, 23:05

@Nico: er hat schon, dass es Vorteile gegenüber den normalen Guards bietet.

Könntet ihr bitte auf meine Antwort schauen, denn da hab ich den Beweis,dass es nicht geht, mehrere Funktionen unterbringen zu können ;)

25

02.12.2007, 23:13

@Nico:

Zitat


Du hast mittlerweile echt Spaß daran mich zu flamen was?

Zitat

In the C and C++ programming languages, #pragma once is a non-standard but widely supported preprocessor directive designed to cause the current source file to be included only once in a single compilation. Thus, #pragma once serves the same purpose as include guards, but in less code and without the possibility for name clashes.


http://en.wikipedia.org/wiki/Pragma_once

Es gehört nicht zum Standard. Damit ist es zu vermeiden. Ein einfaches #ifdef, #define, #endif reicht und ist portabler.
Der einzigste Windows-Code den ich hier sehe, ist die WinMain. Und die kann man auch am besten per #ifdef WIN32 bedingt kompilieren.
Ehm ... du kannst Lesen? Nicht nur Schreiben? Dann ließ mal bitte meine Antwort.
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

XP^

Treue Seele

  • »XP^« ist der Autor dieses Themas
  • Private Nachricht senden

26

02.12.2007, 23:15

Ich weiß nicht wieso oder warum, aber ich kann nur EINE Funktion(und vielleicht nur eine Klasse), die man zu aller erst definiert hat, benutzen.

Hier ist der Beweis:

engine.cpp

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "engine.h"

int WINAPI DllMain(HINSTANCE DllHandle, unsigned long ReasonForCall, void* Reserved)
{
    switch(ReasonForCall)
    {
    case DLL_PROCESS_ATTACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    default:
        break;
    }
    return 1;
}


engine.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef ENGINE_H
#define ENGINE_H

#include <windows.h>

#ifdef ENGINE_EXPORTS
#define ENGINE_API __declspec(dllexport)
#else
#define ENGINE_API __declspec(dllimport)
#endif

#include "test.h"

#endif


test.cpp

C-/C++-Quelltext

1
2
3
4
5
6
#include "engine.h"

void ENGINE_API msg_test()
{
    std::cout << "Hello World!" << std::endl;
}


test.h

C-/C++-Quelltext

1
2
3
4
5
6
7
8
#ifndef TEST_H
#define TEST_H

#include <iostream>

void ENGINE_API msg_test();

#endif



.. so das hab ich kompiliert und hab anschließend die engine.dll ins debug verzeichnis von meinem anderem Projekt hinzugefügt und die beiden Header in das Verzeichnis, wo sich alle source- und headerdateien vom "anderen" Projekt befinden.

main.cpp (anderes Projekt)

C-/C++-Quelltext

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

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

int main()
{
    msg_test();
    std::cin.get();
    return 0;
}


Nun .. sobald ich alles im "anderen" (^^) Projekt geschrieben hab und es dann kompiliere, funktioniert erstmal alles schön und gut!

Aber sobald ich in test.h

C-/C++-Quelltext

1
void ENGINE_API msg_test2();

und in test.cpp

C-/C++-Quelltext

1
2
3
4
void ENGINE_API msg_test2()
{
    std::cout << "Next Text!" << std::endl;
}
und zuletzt noch in der main.cpp (anderes Projekt!!)

C-/C++-Quelltext

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

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

int main()
{
    msg_test();
    msg_test2(); // DAS HIER GEADDED!

    std::cin.get();
    return 0;
}


das vor dem Kommentar reinschreibe und kompiliere, kommt:

Zitat

1>c:\users\daniel\desktop\projekte\uebung\main\main.cpp(16) : error C3861: "msg_test2": Bezeichner wurde nicht gefunden.


Würde mich über hilfreiche Ratschläge freuen und wäre sehr dankbar dafür ;)

Mit freundlichen Grüßen,
Daniel

P.s.: Ich werde langsam angry :p

Nico

Frischling

Beiträge: 82

Wohnort: Nürnberg

  • Private Nachricht senden

27

02.12.2007, 23:27

Kannst mir mal die Projekte als .zip schicken incl. Source oder irgendwo hochladen? Ich würde mir das mal gerne genauer ansehen.
lg

28

02.12.2007, 23:27

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef TEST_H
#define TEST_H

#if (_MSC_VER >= 1300)
#pragma once
#endif // (_MSC_VER >= 1300)


#include <iostream>

void ENGINE_API msg_test_one() { std::cout << "1 ..." << std::endl;  }
void ENGINE_API msg_test_two() { std::cout << "2 ..." << std::endl;  }
void ENGINE_API msg_test_three() { std::cout << "3 ..." << std::endl;  }
void ENGINE_API msg_test_bought() { std::cout << "Meins!" << std::endl;  }

#endif // TEST_H
...
Devil Entertainment :: Your education is our inspiration
Der Spieleprogrammierer :: Community Magazin
Merlin - A Legend awakes :: You are a dedicated C++ (DirectX) programmer and you have ability to work in a team? Contact us!
Siedler II.5 RttR :: The old settlers-style is comming back!

Also known as (D)Evil

XP^

Treue Seele

  • »XP^« ist der Autor dieses Themas
  • Private Nachricht senden

29

02.12.2007, 23:51

@Deviloper .. funktioniert leider noch immer nicht.

Er kann einfach die Funktion nicht finden.

Hier beide Projekte:

http://

und
Konsolenprojekt:

http://

MfG

Nico

Frischling

Beiträge: 82

Wohnort: Nürnberg

  • Private Nachricht senden

30

03.12.2007, 00:09

So funzt es bei mir:

Quellcode

1
2
3
4
5
6
7
int main()
{
    msg_test();
    //msg_test2(); // hier der Fehler
    std::cin.get();
    return 0;
}

Du solltest vllt die "test.h" neu rüberkopieren :P

Zitat


------ Erstellen gestartet: Projekt: main, Konfiguration: Debug Win32 ------
Kompilieren...
main.cpp
Verknüpfen...
Das Manifest wird eingebettet...
Das Buildprotokoll wurde unter "file://[..]/forum\Uebung\main\Debug\BuildLog.htm" gespeichert.
main - 0 Fehler, 0 Warnung(en)
========== Erstellen: 1 erfolgreich, Fehler bei 0, 0 aktuell, 0 übersprungen ==========


Generell würde ich es anders machen hier:
Kopier nicht dauernd hin und her, sondern trenne im DLL-Projekt die includes und die .cpp (versch. Ordner). Dann füge den Ordner mit den includes den Projektoptionen bei denem Client-Programm hinzu^^. Das erspart dir viel Stress :D.
lg

edit: wenn ich die Dateien "test.h" und "engine.h" neu rüberkopiere, kompiliert es auch mit der 2ten Funktion.

Werbeanzeige