Zum Inhalt springen

DLL erstellen und in Projekt einbinden


Astasor

Empfohlene Beiträge

Hallöchen, ich konnte bei Problemen immer auf das Board vertrauen und deshalb komme ich jetzt wieder zu euch zurück

Ich habe eine DLL erstellt und würde sie gerne in einem anderen Projekt nutzen. Mithilfe von LoadLibrary konnte ich die DLL auch laden, aber GetProcAccess gibt mir nicht die Addresse meiner Function aus, obwohl ich sie mit __declspec(dllexport) aus der DLL exportiert und __declspec(dllimport) in das Zweitprogramm importiert habe.

Hier mal mein Code. Ich nehm das PHP-Tag, da es dort schönes Syntax-Coloring gibt. Die erste Zeile ist der jeweilige Name der Datei.

Hier ist der Code von meiner DLL.


#dll.h
#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 */

#include <string>

class DLLIMPORT DllClass
{
public:
DllClass();
virtual ~DllClass(void);

private:

};

__declspec(dllexport) std::string testDll();

#endif /* _DLL_H_ */
[/PHP]

[PHP]
#dllmain.cpp
#include "dll.h"
#include <windows.h>
#include <string>

DllClass::DllClass()
{

}


DllClass::~DllClass ()
{

}

__declspec(dllexport) std::string testDll();

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;
}
std::string testDll(){

std::string test="Die DLL wurde erfolgreich eingebunden.";
return test;

}

Hier ist der Code von meinem Zweitprogramm, indem ich die DLL nutzen will.


#TestDll.cpp
#include "./TestDll.h"
#include <windows.h>

TestDll::TestDll(){
HINSTANCE hInstance;
hInstance = ::LoadLibrary("./../Test/DLL/Test.dll");
pDllFunction = (LPFNDLLFUNC1*)::GetProcAddress((HMODULE)hInstance,"testDll");
}

bool TestDll::CallDllFunction(){
if(pDllFunction){
return true;
}
else{
return false;
}
}
[/PHP]

[PHP]
#TestDll.h
#ifndef _TESTDLL_H_
#define _TESTDLL_H_

#include <string>

class TestDll{
private:
typedef std::string LPFNDLLFUNC1();
LPFNDLLFUNC1 *pDllFunction;
public:
TestDll();
bool CallDllFunction();
};

#endif


#main.cpp
#include <cstdlib>
#include <iostream>
#include <windows.h>
#include "./TestDll.h"
#include <string>

using namespace std;

__declspec(dllimport) string testDll();

int main(int argc, char *argv[])
{

TestDll DllTest;
cout<<DllTest.CallDllFunction()<<endl;

system("PAUSE");
return EXIT_SUCCESS;
}
[/PHP]

Danke das ihr bis hier her gelesen habt. Jetzt noch mal konkret meine Fragen: Was mache ich hier falsch? Sind die Präprozessordirektiven in der dll.h korrekt? Stimmt das typedef in der TestDll.h so, wie es zur Zeit dasteht?

Vielen Dank

mfg Astasor

Link zu diesem Kommentar
Auf anderen Seiten teilen

Schau dir mal mit dem Dependency Walker an, wie die in der DLL exportierte Funktion wirklich heißt.

Da der Name der Funktion wegen der Möglichkeit zur Überladung kein ausreichendes Unterscheidungskriterium ist, muss sich der Compiler etwas anderes einfallen lassen. Er tut dies in Form des sogannten "name mangling". Dabei werden Rückgabetyp und Parametertypen auf bestimmte Art und Weise mit dem Funktionsnamen zu einem neuen Namen verwurstet. Dieser neue Name ist es, den du bei GetProcAddress angeben müsstest.

Benutzt du bewusst Run-Time Dynamic Linking? Würde Load-Time Dynamic Linking ausreichen?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Das mit dem Dependency Walker war ein wirklich guter Tipp. Meine Funktion hatte einen Namen mit Buchstabengewürfel drum rum. Dazu kam noch ein _.

Auf deine erste Frage: Nein. Ich habe gegoogelt wie es geht und bin dabei auf diese Funktionen gestoßen. Was ist der Unterschied zwischen den beiden Verfahren?

Bearbeitet von Astasor
Link zu diesem Kommentar
Auf anderen Seiten teilen

Run-Time Dynamic Linking (Windows)

Was du machst, ist Run-Time Dynamic Linking. Vorteil: Du kannst auch mit DLLs umgehen, die du nicht kennst, oder die sogar fehlen. Dafür musst du dir aber alles selbst heraussuchen. Du brauchst dafür aber weder __declspec(dllimport) noch den Header der DLL.

Deine Funktion CallDllFunction wird übrigens ihrem Namen nicht gerecht, sie ruft nichts auf, sondern prüft nur den Funktionszeiger.

Load-Time Dynamic Linking (Windows)

Mit Load-Time Dynamic Linking bricht dein Programm beim Start mit einem Fehler ab, wenn eine benötigte DLL fehlt. Dafür kannst du die exportierten Funktionen genauso aufrufen, als wären sie lokal definiert.

Dazu musst du dein Programm gegen die kleine statische Bibliothek (.lib) linken, die mit der DLL erstellt wird, die sogenannte Importbibliothek, und den DLL-Header einbinden. Weiter brauchst du nichts.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe noch eine Nachfrage bezüglich des "Name Mangling".

Ich habe bereits danach gegoogelt, doch es scheint niemand je ernsthafte Anstrengungen unternommen zu haben, das zu unterbinden und die Funktionsnamen im Klartext verfügbar zu halten.

Warum ist das so?

Wenn ich eine DLL schreibe, gebe ich sie unter Umständen an jemand anderes weiter und es wäre toll, wenn Derjenige normale Funktionsnamen zum Aufrufen der exportierten Funktionen verwenden könnte und nicht so ein komisches Wortgewürfel.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Warum ist das so?
Weil das Name Mangling in C++ nunmal notwendig ist. Der Name einer Funktion ist nur in C ein eindeutiges Unterscheidungsmerkmal. In C++ gibt es Überladung. Stell dir vor, deine DLL exportiert diese Funktionen:

void foo(int);
void foo(double);[/code]

Wenn beide über den Namen "foo" exportiert werden, wie willst du sie unterscheiden?

Wenn ich eine DLL schreibe, gebe ich sie unter Umständen an jemand anderes weiter und es wäre toll, wenn Derjenige normale Funktionsnamen zum Aufrufen der exportierten Funktionen verwenden könnte und nicht so ein komisches Wortgewürfel.

Wenn man eine DLL weitergibt, benutzt man in aller Regel Load-Time Dynamic Linking, man liefert also Header und Importbibliothek mit aus. Damit sieht der Benutzer nichts vom Name Mangling.

Wenn du absolut Run-Time Dynamic Linking benutzen musst, und deine Funktionen nicht überladen sind, dann definiere sie als extern "C", dann unterbleibt das Name Mangling.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Warum ist das so?

Weil es im C++ Standard nicht standardisiert wurde, deshalb gibt man bei binären Daten dann Compiler & Linker mit an.

Wenn ich eine DLL schreibe, gebe ich sie unter Umständen an jemand anderes weiter und es wäre toll, wenn Derjenige normale Funktionsnamen zum Aufrufen der exportierten Funktionen verwenden könnte und nicht so ein komisches Wortgewürfel.

Weil nicht Du es lesen sollst, sondern die Maschine und außerdem musst Du dann auch einen Standard definieren. Und der Funktionsname reicht nicht, Du brauchst die Signatur der Funktion.

Ich gebe aber mal den Hinweis darauf, dass bei C dieses entsprechend definiert wurde, da C++ den kompletten C Sprachsyntax umfasst, kann man die Einsprungspunkte als C Signaturen definieren und intern weiterhin C++ nutzen.

Link zu diesem Kommentar
Auf anderen Seiten teilen

  • 11 Monate später...

Hallo,

ich würde mich auch für die Erstellung von dll's interessieren. Jedoch vorerst mal für C da ich das gerade in meiner Umschulung durch nehme.

So wirklich brauchbare Tutorials oder infos findet man aber nur zu C++.

Ich arbeite mit Netneans und würde mich über ein paar Tipps und Stichworte zur Recherche freuen.

Gruß Marcus

Link zu diesem Kommentar
Auf anderen Seiten teilen

Netbeans ist eine IDE mit der man auch C/C++ Anwendungen entwickeln kann. Die Tatsache das Netbeans in und für Java geschrieben wurde macht es mir dennoch möglich auch C DLL Projekte anzulegen und zu entwickeln.

Ich bräuchte nur einen Einstiegspunkt um mich darüber zu informieren wie ich explizit Funktionen in dll's auslagere und in einem C Programm einbinde und verwende.

Leider finde ich nur Infos für C++.

Gruß Marcus

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich bräuchte nur einen Einstiegspunkt um mich darüber zu informieren wie ich explizit Funktionen in dll's auslagere und in einem C Programm einbinde und verwende.

Leider finde ich nur Infos für C++.

Es gibt da keine nennenswerten Unterschiede.

Irgendwelche Besonderheiten zu Klassen, Namensräumen und Überladung kannst du ignorieren, weil es so etwas in C nicht gibt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...