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

1

02.12.2007, 14:18

DLL Problem ..

Hallo,

ich übe grad das DLL erstellen :p

Hab aber ein Problem ..

Main.cpp:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <sstream>
#include <string>
#include "functions.h"
#include <vector>

#include "Tutorial.h" 

//Mit diesem Präprozessorbefehl wird die Tutorial.lib mitgelinkt 

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


int main()
{
    Message();
    testmsg("FF");
    std::cin.get();
    return 0;
}


misc.cpp:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
#include "Tutorial.h" 
#include <iostream>
#include <string>

void TUTORIAL_API testmsg(const std::string& any)
{
    std::cout << any << std::endl;
}


misc.h:

C-/C++-Quelltext

1
2
3
#pragma once 

void TUTORIAL_API testmsg(const std::string& any);


Wenn ich das andere Projekt(also "main.cpp") kompiliere, kommt:

Zitat

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


:x

MfG

Nico

Frischling

Beiträge: 82

Wohnort: Nürnberg

  • Private Nachricht senden

2

02.12.2007, 14:33

Eine DLL hat keine normale main().
Denn sie wird ja nicht direkt ausgeführt, sondern eine Anwendung lädt den Code und führt Ihn aus. Unter Win32 gibts nur folgendes:

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
#ifdef WIN32
#include <windows.h>

int WINAPI DllMain( HANDLE _HDllHandle, DWORD _Reason, LPVOID)
{
    switch(_Reason)
    {
        case DLL_THREAD_ATTACH:
        case DLL_PROCESS_ATTACH:
        {
            return TRUE;
        }
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
        {
            return TRUE;
        }
    }
    return TRUE;
}


#endif /* WIN32 */


Und zwecks der Fehlermeldung:
Du solltest die "misch.h" vllt auch in die "main.cpp" einbinden.

edit:
Vermeide "pragma once". C++ ist (solange man keine WinAPI verwendet) XPlatform. Diese Fähigkeit nimmst du deinem Code aber mit solchen Compiler-spez. Befehlen. Ein normaler include-guard tuts auch.
lg

GR-PA

Treue Seele

Beiträge: 326

Wohnort: Daheim

Beruf: Faulenzer

  • Private Nachricht senden

3

02.12.2007, 14:43

@Nico:So wie ich das sehe, ist main.cpp das Programm, dass die dll verwendet also war dort alles richtig.
@XP^ Ist misc.h eingebunden? Eine DllMain solltest du auch definieren, vllt brauchst du sie ja später...
Signaturen werden überbewertet

XP^

Treue Seele

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

4

02.12.2007, 15:08

Zitat von »"GR-PA"«

@Nico:So wie ich das sehe, ist main.cpp das Programm, dass die dll verwendet also war dort alles richtig.


Ja, ich hab zwei Projekte: Test(normales Konsolenprojekt) und Tutorial(DLL), wobei die normale msg funktion vom Tutorial(von Dragonflame) funktioniert und meine nicht :?


Zitat von »"GR-PA"«

@XP^ Ist misc.h eingebunden? Eine DllMain solltest du auch definieren, vllt brauchst du sie ja später...


Ja, ist eingebunden:

tutorial.h:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//Includeguard 

#pragma once 

//Header von außerhalb 

#include <windows.h> 

//Export Makro 

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

//Hier werden alle Header der Dll inkludiert, damit man später nicht 

//in der Anwendung die die Dll verwendet jede einzeln inkludieren muss 

#include "Message.h" 
#include "misc.h"
//#include... 


Und hier ist die DLLMain drinnen:

tutorial.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
// tutorial.cpp : Definiert den Einstiegspunkt für die DLL-Anwendung.

//



#include "tutorial.h" 

//Die DllMain 

int WINAPI DllMain(HINSTANCE DllHandle, unsigned long ReasonForCall, void* Reserved) 
{ 
   switch (ReasonForCall) 
   { 
      case DLL_PROCESS_ATTACH: 
      { 
         //Der Referenzzähler wird um eins erhöht 

      } break; 

      case DLL_PROCESS_DETACH: 
      { 
         //Der Referenzzähler wird um eins reduziert      

      } break; 

      default: break; 
   } 

   return 1; 
}

Databyte

Alter Hase

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

5

02.12.2007, 15:26

Hast du vielleicht vergessen TUTORIAL_EXPORTS bei deiner Dll
zu definieren ?

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

6

02.12.2007, 15:44

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?
@D13_Dreinig

XP^

Treue Seele

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

7

02.12.2007, 16:10

Zitat

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


Es geht mir nur um diesen Fehler :)

Hab doch deklariert usw.. was könnt ich noch vergessen haben?

8

02.12.2007, 16:17

Manchmal nervt es einfach nur wenn hier so pseudoprofis ihr wissen als Wahrheit darstellen:

Zitat

Eine DLL hat keine normale main().
Denn sie wird ja nicht direkt ausgeführt, sondern eine Anwendung lädt den Code und führt Ihn aus. Unter Win32 gibts nur folgendes:

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
#ifdef WIN32
#include <windows.h>

int WINAPI DllMain( HANDLE _HDllHandle, DWORD _Reason, LPVOID)
{
    switch(_Reason)
    {
        case DLL_THREAD_ATTACH:
        case DLL_PROCESS_ATTACH:
        {
            return TRUE;
        }
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
        {
            return TRUE;
        }
    }
    return TRUE;
}

#endif /* WIN32 */

Und zwecks der Fehlermeldung:
Du solltest die "misch.h" vllt auch in die "main.cpp" einbinden.

Bearbeitung
Vermeide "pragma once". C++ ist (solange man keine WinAPI verwendet) XPlatform. Diese Fähigkeit nimmst du deinem Code aber mit solchen Compiler-spez. Befehlen. Ein normaler include-guard tuts auch.

Ehm die MSDN hat gerade einen Aussetze (Runtime Error), von d.h. kann ich dir das jetzt gerade nicht zeigen.
Unter Microsoft Compilern ist ein #pragma once einem gewöhnlichen Include-guard auf jeden Fall vorzuziehen. Benutz einfach mal die Suche in den meisten C++-Foren und du wirst die Vorteile finden. (steht sogar in Wikipedia: http://en.wikipedia.org/wiki/Pragma_once :P) Bei GCC sollte man es nicht nutzen:

Zitat von »"[url=http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC8«

GCC[/url]"]There is also an explicit directive to tell the preprocessor that it need not include a file more than once. This is called `#pragma once', and was used in addition to the `#ifndef' conditional around the contents of the header file. `#pragma once' is now obsolete and should not be used at all.

=>

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
#if !defined(MYHEADER_H__INCLUDED)
#define MYHEADER_H__INCLUDED

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


// ...


#endif // MYHEADER_H__INCLUDED
Hat doch was.

Wofür du in der DllMain überhaupt nen switch drin hast, ist mir schleierhaft aber ist in dem Fall mal egal, weil der Compiler es dir raushauen wird. Und gewöhne dir am besten mal an, wenn ein case-Zweig zu ende sein soll, ein break dahinter zu setzen.
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

Databyte

Alter Hase

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

9

02.12.2007, 16:18

extern "C" ist eigentlich nur sinnvoll, wenn man die Dll
dynamisch läd.

10

02.12.2007, 16:19

Naja nicht nur dann ... du erzwingst ja nur, das die nach dem "Namensmuster" von C benannt werden ...
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

Werbeanzeige