C++ Dll (wahrscheinlich ein komplexes Thema)

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
obbba
Beiträge: 53
Registriert: 06.02.2006 17:33

C++ Dll (wahrscheinlich ein komplexes Thema)

Beitrag von obbba »

Ich wollte gerne mal mit C++ eine Dll schreiben und mit PureBasic ausführen.

Ich habe den C++ Code aus Wikipedia
#include <windows.h>

#if defined(_MSC_VER)
#define DLL __declspec(dllexport)
#else
#define DLL
#endif
// nur unter MS VC das Symbol DLL definieren unter z.B. Linux wird DLL ignoriert

// Die Funktion, die anderen Programmen zur Verfügung gestellt werden soll
// (in diesem Beispiel: Addieren zweier Zahlen)
DLL
double AddNumbers (double a, double b)
{
return a + b;
}
in den Bloodshed Dev-C++ Editor geschrieben und auf kompilieren geklickt (die DLL hat bei mir den Pfad: "H:\Sicherung_alter_cp\Sicherung -D-\FELIX\DevCode\testdll.dll")

Dann hab ich folgenden Code in PureBasic geschrieben:

Code: Alles auswählen

If OpenLibrary(0, "H:\Sicherung_alter_cp\Sicherung -D-\FELIX\DevCode\testdll.dll")
  
  If ExamineLibraryFunctions(0)
    Debug "Die DLL hat "+Str(CountLibraryFunctions(0))+" Funktionen"
    While NextLibraryFunction()
      Debug LibraryFunctionName()
    Wend
    Debug "Das war die letzte Funktion"
  Else
    Debug "Kann nicht untersucht werden"
  EndIf
  
  If IsFunction(0,"AddNumbers")
    Debug "AddNumbers gibt folgendes aus:"
    Debug CallCFunction(0,"AddNumbers",3,4)
  Else
    Debug "AddNumbers gibts nicht"
  EndIf
  
  CloseLibrary(0)
Else
  Debug "Kann nicht geöffnet werden"
EndIf

Und der Debbuger gibt das aus:
Die DLL hat 64 Funktionen
Das war die letzte Funktion
AddNumbers gibts nicht
Eigentlich hätte ich gerne, dass der mir die Namen der angeblich 64 Funktionen angibt. Und natürlich das AddNumbers funktioniert.

/edit:
vieleicht sollte ich das DLL im C++ Code direkt vor die Funktion schreiben? Wenn das so eine Art Typ ist?
PureBasic v3.94 (Windows - x86) (Demo)
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

// nur unter MS VC das Symbol DLL definieren unter z.B. Linux wird DLL ignoriert
Vielleicht liegts daran, dass du MingW nutzt und nicht MS VC?
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
inc.
Beiträge: 348
Registriert: 27.10.2004 12:25

Beitrag von inc. »

Gehe in DevC++ hin und nutze im Wizard "C Project" oder so, nicht C++.
Dann müsste der Code auch ohne Extern "C" { ...... Hier die Codezeilen ... } auskommen.

Gehe generell hin und nutze am Anfang den Dll Wizard von DevC++, sodann brauchst du nur deine Functionen einsetzen und als Dll kompilieren.
Neues Project / Basic / DLL

Oder in einem C++ Project:

Code: Alles auswählen

#ifdef __cplusplus
extern "C"
{
#endif
    .... // Hier stehen die Funktionsdeklarationen
#ifdef __cplusplus
}
#endif
http://www.cpp-tutor.de/cpp/le07/le07_03_d1.htm

Also imho so ungefähr:

Code: Alles auswählen

#include <windows.h>

#if defined(_MSC_VER)
#define DLL __declspec(dllexport)
#else
#define DLL
#endif
// nur unter MS VC das Symbol DLL definieren unter z.B. Linux wird DLL ignoriert

#ifdef __cplusplus
extern "C" {
#endif

// --------- Hier die unten definierten Funktionen vorher deklarieren -----

DLL double __stdcall AddNumbers (double a, double b);

#ifdef __cplusplus
}
#endif


// Die Funktion, die anderen Programmen zur Verfügung gestellt werden soll
// (in diesem Beispiel: Addieren zweier Zahlen)
DLL double __stdcall AddNumbers (double a, double b)
{
  return a + b;
} 
(Habe __stdcall als Aufrufskonvention genutzt, sodann kannst du "Import" anstatt "ImportC" nutzen, falls PB die Funktionen als __Cdecl nicht richtig erkennt.)


Da du eh die Dll selbst erstellst und du somit dann auch nach dem Kompilieren die "testdll.lib" im Ordner haben solltest, ist es eleganter diese auch als Wrapper zu nutzen, wie man es in C/C++ auch macht:

Code: Alles auswählen

Import "X:/Pfad/zur/testdll.lib"
  AddNumbers.d (a.d, b.d)
EndImport

debug AddNumbers (1.23456789034, 5.34532455666)
Sodann steht dir die Funktion aus der Dll wie ein nativer PB Command zur Verfügung. Die DLL muss sodann im Compiler Ordner von PB liegen (innerhalb deiner Entwicklungsphase), am Ende muss diese beim User im Ordner deiner fertigen Appl. sein, ist klar.
Den ganzen OpenLibrary() etc. Kram brauchst du somit bei eigenen DLLs wo auch lib's beim Kompilieren rauskommen nicht mehr, denn PB kann via Import statisch linken -> einer der ganz großen Vorteile von PB4.

Alles hier aus'm Kopf getippt (-> keine Gewähr), aber die Logic sollte klar sein.

EDIT: Falls PB via "Import" die Funktionsnamen nicht erkennt, dann eine "Testdll.def" Datei im Project von DevC++ mit folgenden Inhalt anlegen:

Code: Alles auswählen

LIBRARY Testdll.dll
EXPORTS
  AddNumbers
Zuletzt geändert von inc. am 29.07.2006 19:15, insgesamt 1-mal geändert.
Hier gibts die OOP Option für PureBasic.
Benutzeravatar
obbba
Beiträge: 53
Registriert: 06.02.2006 17:33

Beitrag von obbba »

Gehe generell hin und nutze am Anfang den Dll Wizard von DevC++, sodann brauchst du nur deine Functionen einsetzen und als Dll kompilieren.
Aber wo?
Ich muss zugeben, dass ich noch nicht so gut C++ kann.

Wenn ich deinen Code eingebe kommt die Fehlermeldung "[Linker Error] undefined referece to 'WinMain@16'"

So wie ich das verstanden habe bedeuted das, dass die main() funktion fehlt. Aber so was brauch eine DLL doch gar nicht, oder ?

Danke trotzdem für die Mühe!
Zuletzt geändert von obbba am 29.07.2006 19:35, insgesamt 2-mal geändert.
PureBasic v3.94 (Windows - x86) (Demo)
Benutzeravatar
inc.
Beiträge: 348
Registriert: 27.10.2004 12:25

Beitrag von inc. »

Wenn ich deinen Code eingebe kommt die Fehlermeldung "[Linker Error] undefined referece to 'WinMain@16'"
Weil du als Exe kompilierst und nicht als Dll. Eine Dll kommt in Windows mit einer DllMain und eine Exe mit einer WinMain Funktion daher.

In DevC++ rufst du ein neues Projekt auf, dann wählst du das wie hier gezeigt aus:
(also in DevC++ "Neues Projekt" und hier "Dll" und "C Project" auswählen)
Bild
In jenem DLL Project ist dann die DllMain Funktion enthalten. Wenn ich ein Projekt anlege wie du es brauchst, bekomme ich das hier raus:
(die BeispielFunktion mit der deinigen ersetzt und __stdcall hinzugefügt.)

dll.h

Code: Alles auswählen

#ifndef _DLL_H_
#define _DLL_H_

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */


DLLIMPORT double __stdcall AddNumbers (double a, double b); // ** Die Deklaration deiner Funktion **


#endif /* _DLL_H_ */
dllmain.c

Code: Alles auswählen

/* Replace "dll.h" with the name of your header */
#include "dll.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

DLLIMPORT double __stdcall AddNumbers (double a, double b) // ** Die Definition deiner Funktion **
{
  return a + b;
}


BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}
Die ... Extern "C" Aufrufe wie im obigen Post brauchst du hier nicht, da du ein "C" Projekt angelegt hast (siehe Bild)
Hier gibts die OOP Option für PureBasic.
Benutzeravatar
obbba
Beiträge: 53
Registriert: 06.02.2006 17:33

Beitrag von obbba »

Mit C gehts.

Danke. :allright: :allright: :allright:


Wenn ich das gleiche mit C++ mache kommt was mit Klassen.
Ich werde mir die Objektorientierte Programmierung mal im Tutorial durchnehmen, vieleicht verstehe ich es dann.
PureBasic v3.94 (Windows - x86) (Demo)
Benutzeravatar
inc.
Beiträge: 348
Registriert: 27.10.2004 12:25

Beitrag von inc. »

obbba hat geschrieben:Ich werde mir die Objektorientierte Programmierung mal im Tutorial durchnehmen, vieleicht verstehe ich es dann.
http://www.robsite.de/tutorials.php?tut=c
Schaue dir mal den " Volkhards C++ Kurs" an.
Hier gibts die OOP Option für PureBasic.
Antworten