# Cmake Shared_Lib Link Problem



## GreedyRaccoon (16. Juli 2010)

Hey Leute

Ich habe eine Problem mit dem Linken von selbst erstellten SHARED_LIBS per Cmake

Ich erstelle aus einem Visual Studio Projekt mittels CMAKE eine Shared LIB mit folgendem Code:
ADD_LIBRARY( Toolbox SHARED ${ToolboxSrcs})
so schön so gut, damit bekomme ich in meinem /release Ordner eine .lib und eine .dll datei

Diese würde ich jetzt gerne mit einem anderen Programm verwenden und verwende dafür folgenden CMAKE Code:

FIND_LIBRARY(TOOLBOX_VAR "Toolbox" SHARED_ONLY ../Toolbox/release/)
ADD_LIBRARY(TOOLBOX_LIB SHARED ${TOOLBOX_VAR})
SET_TARGET_PROPERTIES(TOOLBOX_LIB PROPERTIES LINKER_LANGUAGE CXX)
TARGET_LINK_LIBRARIES( TMSTools

${TOOLBOX_LIB}
.
.
.
.

)
Das Funktioniert soweit auch und in meinem TMSTools Projekt sehe ich die Toolbox lib auch integriert.

Beim Compilieren jedoch bekomme ich folgende Fehlermeldung die auch nach mittlerweile stundenlangem recherchieren nicht weggeht:
Error 2 error LNK2001: unresolved external symbol _DllMainCRTStartup TOOLBOX_LIB

Irgendjemand eine Idee? Such da jetzt wirklich schon lang dran,
danke, lg
Andreas


----------



## ComFreek (16. Juli 2010)

Eine externe Datenquelle fehlt.

Wahrscheinlich hast du eine Lib oder DLL vergessen mit einzubinden.


----------



## GreedyRaccoon (16. Juli 2010)

Danke für die Antwort

Wie überprüfe ich ob ich beide eingebunden habe / oder kann es sein, dass ich in der shared lib TOOLBOX irgendwo einen entry ponit definieren muss bzw wie sage ich dem compiler, dass es keinen entry point gibt?

vielen dank!


----------



## ComFreek (16. Juli 2010)

Gute Vermutung. Ja, es kann sein, dass du keinen EntryPoint definiert hast, denn folgende Meldung bestätigt das:

```
_DllMainCRTStartup
```
Ich glaube aber, dass jedes Programm einen EntryPoint haben muss.

Theoretisch könntest du auch einfach einen leeren EntryPoint machen:

```
// Ungefähr so

... ToolBoxEntryPoint(...)
{
  // Ist einfach nur so da
}
```


----------



## GreedyRaccoon (16. Juli 2010)

ok und wie bringe ich cmake und somit dem nächsten Programm bei, dass genau die funktion der entrypoint ist?

Und was hat das ganze vielleicht damit zu tun 
http://msdn.microsoft.com/en-us/library/ms682583(VS.85).aspx


----------



## ComFreek (16. Juli 2010)

Einfach diese Funktion schreiben, z.B: so:

```
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, in  LPVOID lpvReserved)
{
  // Tue nichts
}
```

Aber eigentlich ist die Funktion dafür, gedacht etwas zu initialisieren oder zu löschen (z.B. Variablen).
Darf ich fragen, für was die ToolBox sein soll?


----------



## GreedyRaccoon (16. Juli 2010)

Sehr gerne darfst du fragen ;-)

Die toolbox soll eine Ansammlung grundlegender C++ Funktionen sein.

Also beispielsweise gibt es eine Klasse DataTool welche eine Sammlung statischer Funktionen für File/Folder Handling ist
Dann gibt es BasicTool welche eine Sammlung grundlegender Funktionen für string/integer/.... Handling ist.

Alle diese Klassen möchte ich in eine dll packen damit anschließend sie verwendende Programme die ganzen grundlegenden Funktionen nicht jedesmal neu compilieren müssen.


----------



## GreedyRaccoon (16. Juli 2010)

YICHA Ok habe jetzt folgendes unternommen:

Ich habe meinem Toolbox Project folgendes File hinzugefügt:

EntryPoint.cxx
------------------------------
#include <windows.h>
bool __declspec(dllexport)  WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason,  LPVOID lpvReserved)
{
  // Tue nichts
}
-----------------------------

Weiters habe ich die CmakeLists erweiters:

Toolbox CmakeLists
-----------------------------
ADD_LIBRARY( Toolbox SHARED ${ToolboxSrcs})
set_target_properties(Toolbox PROPERTIES  LINK_FLAGS "/ENTRY:\"DllMain\"")
-----------------------------

neues Program welches Toolbox einbinden soll:
------------------------------
FIND_LIBRARY(TOOLBOX_VAR "Toolbox" SHARED_ONLY  ../Toolbox/release/)
ADD_LIBRARY(TOOLBOX_LIB SHARED   ${TOOLBOX_VAR})
SET_TARGET_PROPERTIES(TOOLBOX_LIB PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(TOOLBOX_LIB PROPERTIES  LINK_FLAGS "/ENTRY:\"DllMain\"")
------------------------------

und voila ! der Fehler ist mal fürs erste weg.

.... jetzt bleibt nur noch das Problem, wie ich auf die Funktionen in der dll zugreifen kann ... ? 

ich exportere BasicTool.h beispielsweise so:

-----------------------
namespace Toolbox
{
	class __declspec(dllexport) BasicTool  
	{
		public: 


			static  string intToString(int number);
			static string	doubleToString(double number);
.
.
.
---------------------------------

Was müsst ich jetzt im importierenden Project in einer Klasse schreiben damit ich auf intToString von BasicTool zugreifen kann?

vielen dank hat mich schon weiter gebracht


----------



## ComFreek (16. Juli 2010)

Ich habe folgendes gefunden: Click!

Also du machst noch eine Datei, z.B. "toolbox.h":

```
#ifndef __MAIN_H__
#define __MAIN_H__

#include <windows.h>

/*  To use this exported function of dll, include this header
 *  in your project.
 */

#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif


#ifdef __cplusplus
extern "C"
{
#endif

  void DLL_EXPORT SomeFunction(const LPCSTR sometext);  // Deklariere hier deine Funktionen

#ifdef __cplusplus
}
#endif

#endif // __MAIN_H__
```

Diese bindest du in dein Programm ein (per #include.


----------



## GreedyRaccoon (16. Juli 2010)

yeah  danke step by step ;-)

das mit dem header hab ich schon öfter gesehen das dürfte so funktionieren

ich habe also eine DLLDefines.h mit dem ganzen "DLL_EXPORT ifdef" ... zeugs

und mein BasicTool folgendermaßen definiert:

class DLL_EXPORT BasicTool  
{
		public: 


			static  string intToString(int number);
			static string	doubleToString(double number);
.
.
.
};


im neuen Projekt versuch ich BasicTool jetzt folgendermaßen zu importieren:
#ifdef __cplusplus
extern "C++"
{
#endif

  class DLL_EXPORT BasicTool;  // Deklariere hier deine Funktionen

#ifdef __cplusplus
}
#endif

.... er meckert zwar nicht, ich kann BasicTool aber immer noch nicht verwenden ... ^^

ne idee?


----------



## ComFreek (16. Juli 2010)

GreedyRaccoon hat gesagt.:
			
		

> vielen dank hat mich schon weiter gebracht
> yeah danke step by step ;-)


Ich will nicht irgendwie betteln, aber es gibt einen Danke-Button 


Wie sieht denn dein Code aus, in dem du BasicTool verwenden möchtest.

In deinem DLL-Projekt solltest du ungefähr diese Dateistruktur haben:

BasicTool.cpp
AdvancedTool.cpp
...
*Defines.h*

Jetzt versuche mal folgenden Code zu kompilieren/auszuführen:

```
#include "dll/defines.h"

int main()
{
  BasicTool::SayHello();
}

/* BasicTool::SayHello könnte so aussehen:
    
    void BasicTool::SayHello()
    {
      MessageBox(NULL, "Test", "Test", 0);
    }
*/
```

EDIT: Benutze doch bitte die C++ Tag: *[code=cpp]Your code[/code]*


----------



## GreedyRaccoon (16. Juli 2010)

> es gibt einen Danke-Button



Tatsächlich ;-) *pressed*


Ok ich versuche hier mal meine Struktur aufzubauen

Die Idee ist es wie gesagt ein Bibliotheken System verschiedener Spezialisierung aufzubauen dass dann seperat von komplexen Anwendungen verwendet werden kann.

Im momentanen Fall ist es die "Grundlagen Bibliothek" Toolbox die von einer spezialisierteren Bibliothek "TMSTools" verwendet werden soll. Beide sollen dann in weiterer Folge von einer Application verwendet werden.

Die Struktur:

Toolbox:

```
==================================
>>> DLLDefines.h
#ifndef __MAIN_H__
#define __MAIN_H__
 
#include <windows.h>
 
/*  To use this exported function of dll, include this header
 *  in your project.
 */
 
#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif

#endif

==================================
>>>BasicTool.h
#include "DLLDefines.h"
// andere includes

namespace Toolbox
{
	class DLL_EXPORT BasicTool  
	{
		public: 
		
			
			static   string intToString(int number);
			static string	doubleToString(double number);
			static QString	intToQString(int number);
			static int		stringToInt(string text);
                         // some more functions
		};

}

==================================
>>>EntryPoint.h
#include <windows.h>
#include <BasicTool.h>
//#include "DLLDefines.h"
bool __declspec(dllexport)  WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason,  LPVOID lpvReserved)
{
  // Tue irgendwos
}

==================================
>>>CmakeLists.txt

ADD_LIBRARY( Toolbox SHARED ${ToolboxSrcs})
set_target_properties(Toolbox PROPERTIES  LINK_FLAGS "/ENTRY:\"DllMain\"")
```

TMSTools:

```
Besitzt die selbe DLLDefines.h

==================================
>>>InputTester.h
#include "DLLDefines.h"

using namespace std;
//==================================
//	INPUT DEFINITIONS
#ifdef __cplusplus
extern "C++"
{
#endif
 
	//string DLL_EXPORT intToString(int number);
  class DLL_EXPORT BasicTsdfsdfool;  // Deklariere hier deine Funktionen
 
#ifdef __cplusplus
}
#endif
//=================================

class  ImportTester
{
public:
	ImportTester();
	~ImportTester();
};
#endif

==================================
>>>ImportTester.cxx

#include "ImportTester.h"

ImportTester::ImportTester()
{
	string bla = BasicTool::intToString(1);
}

==================================
>>>CmakeLists.txt
FIND_LIBRARY(TOOLBOX_VAR "Toolbox"  ../Toolbox/release/)
ADD_LIBRARY(TOOLBOX_LIB SHARED   ${TOOLBOX_VAR})
SET_TARGET_PROPERTIES(TOOLBOX_LIB PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(TOOLBOX_LIB PROPERTIES  LINK_FLAGS "/ENTRY:\"DllMain\"")
```

--> Fehler Meldung dass BasicTool nicht bekannt ist


----------



## ComFreek (16. Juli 2010)

Danke für den Dank 

Du hast ja auch nicht in die "Defines.h" deine Klasse deklariert, so müsste es ausschauen:

```
==================================
>>> DLLDefines.h
#ifndef __DLLDEFINES_H__
#define __DLLDEFINES_H__
 
#include <windows.h>
 
/*  To use this exported function of dll, include this header
 *  in your project.
 */
 
#ifdef BUILD_DLL
    #define DLL_EXPORT __declspec(dllexport)
#else
    #define DLL_EXPORT __declspec(dllimport)
#endif
 
 
#ifdef __cplusplus
extern "C"
{
#endif
 
  class BasicTool;
 
#ifdef __cplusplus
}
#endif
 
#endif // __DLLDEFINES_H__
==================================
```
*Ich bin mir aber nicht ganz sicher, wie das mit dem namespace zu handhaben ist. Probier es einfach aus *

*Du solltest eventuell die Namen bei den #defines abändern (habe ich hier schon gemacht)*


----------



## GreedyRaccoon (16. Juli 2010)

Gern geschehen ;-)


Ok habe die DLLDefine.h jetzt so umgebaut und den namespace rund um BasicTool mal vorsorglich entfernt aber er erkennt BasicTool im InputTester.cxx immer noch nicht ....

Wie könnte ich denn überprüfen ob die dll überhaupt richtig geladen wurde? Gibts da einen Befehl?


update:

Ok ich bin mir sicher, dass die library richtig eingebunden ist weil:

Wenn ich im BasicTool.h direkt die Funktion mit dem Export befehl kennzeichne und dann

.) die Funktion im TMSTool direkt mit dem Export einbinde bekomme ich eine Fehler Funktion für ein unreferenced extern symbol

```
Error	2	error LNK2019: unresolved external symbol 
"__declspec(dllimport) class std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> > __cdecl intToString(int)" 
(__imp_?intToString@@YA?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@Z)
 referenced in function
 "public: __cdecl ImportTester::ImportTester(void)"
 (0ImportTester@@QEAA@XZ)	ImportTester.obj
```
.) eine beliebige nicht existierende Funktion verwende, bekomme ich ein Warning dass aus der Library nix importiert wird


Das selbe passiert auch beim importieren von BasicTool oder eben nicht

Importiere ich es nicht oder einen beliebigen Namen, gibt es das Warning 

```
Warning	1	warning LNK4001: no object files specified; libraries used	TOOLBOX_LIB
```
Bei import BasicTool kein warning aber ich kanns noch nicht verwenden.....

... aahh ich glaub wir sind ganz nah dran


----------



## ComFreek (16. Juli 2010)

GreedyRaccoon hat gesagt.:


> Ok habe die DLLDefine.h jetzt so umgebaut und den namespace rund um BasicTool mal vorsorglich entfernt aber er erkennt BasicTool im InputTester.cxx immer noch nicht ....



Was heißt "nicht erkennen". Heißt das, dass der Compiler sagt: "undefined type" oder so? Das kann irgendwie nicht sein, kannst du deine Dateien mal als ZIP hochladen?

*Edit: Im DLL-Projekt, hast du da #define BUILD_DLL angegeben, denn sonst greifen nicht die Funktionen DLL_EXPORT in Defines.h?*


----------



## ComFreek (16. Juli 2010)

Ich guck es mir mal an. Dann schreibe ich wieder hier rein.

*Der Windows-Explorer meldet mir, dass der ZIP-Ordner ungültig sei! Lade ihn noch mal hoch*


----------



## GreedyRaccoon (16. Juli 2010)

benens mal in *.rar um, habs in zip unbenannt weil ichs sonst nicht hochladen konnt

--> nochmal direkt als zip


----------



## ComFreek (16. Juli 2010)

Ok, klappt.

*Ich guck es mir mal an. Dann schreibe ich wieder hier rein.*


----------



## GreedyRaccoon (16. Juli 2010)

Das Problem ist, es gibt zu wenige [DANKE] Buttons hier!

Boah ich hoffe echt, dass ich das irgendwann hinbekomme, sitze da echt schon lange dran.


DANKE DANKE DANKE !!
;-)


----------



## ComFreek (16. Juli 2010)

Es gibt noch die BEWERTEN-Buttons 

Es sind ziemlich viele Dateien und ich habe kein Visual Studio. Ich habe Code::Blocks, damit habe ich die "Solution" importiert. Doch der Compiler (MinGW) sagt, dass er einige Dateien (die mit "q" anfangen) nicht finden kann.

Naja, der Fehler besteht darin, dass dem Compiler der Typ BasicTool nicht bekannt ist. Bist du dir wirklich wirklich sicher (bei den ganzen Dateien, muss man mehrmals fragen ), dass du die "DLLDefines.h" eingebunden hast?


----------



## GreedyRaccoon (16. Juli 2010)

Yo du hast recht, die "Solution" is a bissl zu groß zum austesten.

Ich werde am Montag eine minimal version des ganzen bauen und dann schauen ob und wies funktioniert, dann sind die wege hoffentlich auch besser nachvollziehbar.

*--> So das Problem hat mich nicht in Ruhe gelassen, bin daher heut gleich noch schnell ins Büro gefahren und habe diese Testversion aufgesetzt.*

Stellvertredend für Toolbox und TMSTools habe ich mit CMAKE zwei VS 08 Projekte erstellt welche genau den Vorgang nachempfinden sollen (DLLExport) (DLLImport).

Daher:
 DLLExport soll seine eine Klasse ExportClass in eine precomiled library verpacken, welche dann von ImportClass in DLLImport verwendet werden soll (ohne sie neu zu kompilieren).
Ich bekomme zurzeit die selbe Fehlermeldung wie gestern, vielleicht kannst du es aber mit diesen Files besser nachvollziehen!

Ich hänge zwei Archive an. Das eine beinhaltet die fertigen VS08 Projekte, das andere nur die c++ files mit dazugehöriger CMakeLists.txt.

mittel dieser kannst du mittels des Programms http://www.cmake.org/ eine Solution für deinen Compiler erstellen.

Wünsche weiterhin noch ein schönes Wochenende,
lg,
Andreas


----------



## ComFreek (18. Juli 2010)

Ok, ich habe nur die C++ Codes genommen. Dann habe ich deine DLL erstellt. Doch wenn ich den anderen Code erstellen will, sagt MinGW (habe eine Klasse TAuto implementiert):

```
C:\...\import\main.cpp|11|error: aggregate `TAuto a' has incomplete type and cannot be defined
```

Doch bei einer Funktion:

```
obj\Release\main.o:main.cpp:(.text+0x3d)||undefined reference to `SquareNumber'|
```

Jetzt bin ich selber verwirrt!!


----------



## GreedyRaccoon (18. Juli 2010)

hmm

wieso main.cpp ? in den zwei bibs gabs ja gar keine main.cpp da es ausschließlich zwei Funktionsbibliotheken sein sollten.


Vielleicht ist beim erstellen mit CMAKE was schiefgelaufen?

... ich komme immer noch nicht dahinter warum er die dll nicht erkennt, denn in der Solution implementiert er sie, er findet den entry point, aber wenn ich die Klasse über die DLL_EXPORT funktion importieren möchte erkennt er sie nacher nicht ....


----------



## ComFreek (18. Juli 2010)

Ich mir nochmals ein eigenes Projekt gemacht. Habe aber mit MinGW kompiliert.

Vielleicht kann ja ein anderer helfen. Ich bin jetzt ech überfragt. Aber vielleicht kann ich morgen besser denken 



> Vielleicht ist beim erstellen mit CMAKE was schiefgelaufen?


Meiner Meinung, kann kein Computer auf dieser Welt was Falsches machen. Entweder ist der Programmierer oder der Anwender schuld! 

*EDIT: Ich glaube, das Problem hängt mit Klassen zusammen. Denn bei meiner Google-Recherche wegen diesem Fehler bin ich darauf gestoßen, das die Deklaration woanders sein muss. Mehr habe ich aber nicht erfahren, naja...*


----------



## deepthroat (19. Juli 2010)

Hi.

@GreedyRaccoon: Du solltest evtl. mal ein paar Tutorials bzw. die Hilfe von CMake lesen.

CMake definiert automatisch eine ${PROJECT_NAME}_EXPORTS Präprozessorvariable wenn eine DLL erstellt wird.

Du hast die DLLExport Bibliothek im DLLImport Projekt nochmal definiert, was einfach Unfug ist.

Du hast die ExportClass.h Datei nicht in ImportClass.cxx eingebunden. Es ist unsinnig die Klassen im DLLImport Projekt zu definieren.

Du darfst die DLLDefines.h nicht in beiden Projekten unterschiedlich definieren bzw. keine Include-Guards verwenden. So ist die DLLImport DLL unbrauchbar, da DLL_EXPORT global auf dllimport gesetzt ist und man so . Am besten definierst du für jede Bibliothek eine eigene DLL_EXPORT Variable.


```
# DLLImport CMakeList.txt

PROJECT(DLLImport)
cmake_minimum_required(VERSION 2.6)

# Use the include path and library for Qt that is used by VTK.
INCLUDE_DIRECTORIES(
  ${CMAKE_CURRENT_BINARY_DIR}
  ${CMAKE_CURRENT_SOURCE_DIR}
  ../DLLExport
)

# ************************************************************************************
# ------------------- Main Program with User Interface -------------------------------
# ************************************************************************************

SET (DLLImportSrcs
	DLLDefines.h
	ImportClass.h
	ImportClass.cxx
)


#----------------------------------
LINK_DIRECTORIES(../DLLExport/release/)
FIND_LIBRARY(DLLEXPORT_VAR "DLLExport"  ../DLLExport/release/)

# ----- LINK SELF --------------
ADD_LIBRARY( DLLImport SHARED ${DLLImportSrcs})
SET_TARGET_PROPERTIES(DLLImport PROPERTIES LINKER_LANGUAGE CXX)

TARGET_LINK_LIBRARIES( DLLImport ${DLLEXPORT_VAR})
```


```
// DLLExport DLLDefines.h 
#ifdef DLL_EXPORT
#  undef DLL_EXPORT
#endif

#ifdef DLLExport_EXPORTS
#  define DLL_EXPORT  __declspec(dllexport)
#else
#  define DLL_EXPORT __declspec(dllimport)
#endif
```


```
// DLLImport DLLDefines.h
#ifdef DLL_EXPORT
#  undef DLL_EXPORT
#endif

#ifdef DLLImport_EXPORTS
#  define DLL_EXPORT  __declspec(dllexport)
#else
#  define DLL_EXPORT __declspec(dllimport)
#endif
```


```
// ImportClass.cxx
#include "ImportClass.h"
#include "ExportClass.h"

...
```
Gruß


----------



## GreedyRaccoon (19. Juli 2010)

Guten Morgen!
Vielen Dank für den Input.




deepthroat hat gesagt.:


> ```
> # DLLImport CMakeList.txt
> 
> PROJECT(DLLImport)
> ...


Genau so eine CmakeLists.txt hatte ich bevor ich das hier beschriebenen Problem anfing.  Das Problem mit dem Header einbinden (#include ExportClass.h) ist, dass bei jedem Kompiliervorgang die exportClass neu kompiliert wird. Bei größeren Projekten wird es mühsam die grundlegenden Klassen die sich nicht mehr ändern jedesmal neu kompilieren zu müssen.

Deshalb wollte ich eine precompiled SHARED Library, grundlegender Funktionen, erzeugen, aus der ich ohne neu kompilieren zu müssen die Klassen verwenden kann. (in C# ging das ohne Probleme meine Frage ist wie und ob dies mit C++ und CMAKE funktioniert)

Ich habe soeben diesen Artikel gelesen der schreibt, dass man wie gehabt die *.lib (wie oben stehend) verlinkt UND die dll in die runtime library kopieren muss
http://www.cmake.org/pipermail/cmake/2009-November/033349.html


```
.
.
#=============== LINK DLL EXPORT ====================================================
// ----- Link .lib
LINK_DIRECTORIES(../DLLExport/release/)
FIND_LIBRARY(DLLEXPORT_VAR "DLLExport"  ../DLLExport/release/)
ADD_LIBRARY(DLLEXPORT_LIB SHARED   ${DLLEXPORT_VAR})
SET_TARGET_PROPERTIES(DLLEXPORT_LIB PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(DLLEXPORT_LIB PROPERTIES  LINK_FLAGS "/ENTRY:\"DllMain\"")
//------------------------

//---- Copy .dll to runtime directory
                 INSTALL(FILES ../DLLExport/release/DLLExport.dll
                     DESTINATION ./Release/
                     CONFIGURATIONS Release
                     COMPONENT Applications)

ADD_CUSTOM_TARGET(DLLEXPORT-Release-Copy ALL
                             COMMAND ${CMAKE_COMMAND} -E
			copy_if_different ../DLLExport/release/DLLExport.dll
                        ${CMAKE_CURRENT_SOURCE_DIR}/Release/     
                        COMMENT "Copying ../DLLExport/release/DLLExport.dll to ${CMAKE_CURRENT_SOURCE_DIR}/Release/"

                             )
#===================================================================================
.
.
```

So weit so gut ... er kopiert die dll in das directory, jetzt muss ich nur noch schaffen die klassen einzubinden
lg,
Andreas


----------



## deepthroat (19. Juli 2010)

GreedyRaccoon hat gesagt.:


> Genau so eine CmakeLists.txt hatte ich bevor ich das hier beschriebenen Problem anfing.  Das Problem mit dem Header einbinden (#include ExportClass.h) ist, dass bei jedem Kompiliervorgang die exportClass neu kompiliert wird. Bei größeren Projekten wird es mühsam die grundlegenden Klassen die sich nicht mehr ändern jedesmal neu kompilieren zu müssen.


Der Code sollte sich in den CPP Dateien befinden. Die Header müssen in C++ *immer *eingebunden werden.

Um die Implementation zu verstecken und (ohne Neukompilieren) ändern zu können kann man in C++ das Pimpl Idiom anwenden. 

Wenn du nicht die vollständige Definition der Klassen benötigst (also nur mit Zeigern hantierst), reicht auch eine Vorwärtsdeklaration aus, aber wenn du eine Instanz einer Klasse erstellen willst, muss die vollständige Definition der Klasse vorliegen.

Nochmal zum Mitschreiben. Das hier ist kompletter Unsinn:





GreedyRaccoon hat gesagt.:


> ```
> ADD_LIBRARY(DLLEXPORT_LIB SHARED   ${DLLEXPORT_VAR})
> SET_TARGET_PROPERTIES(DLLEXPORT_LIB PROPERTIES LINKER_LANGUAGE CXX)
> set_target_properties(DLLEXPORT_LIB PROPERTIES  LINK_FLAGS "/ENTRY:\"DllMain\"")
> ```


Das hier auch:


GreedyRaccoon hat gesagt.:


> ```
> INSTALL(FILES ../DLLExport/release/DLLExport.dll
> DESTINATION ./Release/
> CONFIGURATIONS Release
> ...


Das Install Target wird nicht beim Kompilieren ausgeführt. Es ist dazu da, das endgültige Programm und die Bibliotheken im System zu installieren. Deswegen gehört dieser Code (wenn überhaupt) in das DLLExport Projekt.

Du könntest auch eine statische Bibliothek erstellen, die läßt sich einfacher nutzen.

Gruß


----------



## GreedyRaccoon (19. Juli 2010)

deepthroat hat gesagt.:


> Der Code sollte sich in den CPP Dateien befinden. Die Header müssen in C++ *immer *eingebunden werden.


*Ok, gibt es eine Möglichkeit die HeaderFiles direkt aus der dll zu beziehen oder müssen die *.h Files immer in einem Directory verfügbar sein?*



deepthroat hat gesagt.:


> Um die Implementation zu verstecken und (ohne Neukompilieren) ändern zu können kann man in C++ das Pimpl Idiom anwenden.


*gesucht* klingt super danke für den Tipp!!



deepthroat hat gesagt.:


> Du könntest auch eine statische Bibliothek erstellen, die läßt sich einfacher nutzen.


Yo das habe ich ja vorher gemacht, wollte auf SHARED umsteigen um die Kompilierzeit zu verkürzen, was mich aber offenbar auf einen Irrweg gebracht hat.


----------



## deepthroat (19. Juli 2010)

Hi.





GreedyRaccoon hat gesagt.:


> *Ok, gibt es eine Möglichkeit die HeaderFiles direkt aus der dll zu beziehen oder müssen die *.h Files immer in einem Directory verfügbar sein?*


Letzteres.

Gruß


----------



## GreedyRaccoon (19. Juli 2010)

Ok, 

Vermutlich eine blöde Frage, aber was bringt mir die *.dll dann überhaupt wenn es sowieso nur über 

```
LINK_DIRECTORIES(${DLLEXPORT_PATH})
FIND_LIBRARY(DLLEXPORT_LIB "DLLExport"  ${DLLEXPORT_PATH})
```

also einbinden des *.lib files und verlinken des HeaderDirectories funktioniert?


----------



## deepthroat (19. Juli 2010)

GreedyRaccoon hat gesagt.:


> Ok,
> 
> Vermutlich eine blöde Frage, aber was bringt mir die *.dll dann überhaupt wenn es sowieso nur über
> 
> ...


Die .lib Datei der DLL enthält Informationen über die exportierten Symbole (Variablen, Funktionen, Klassen) die die DLL zur Verfügung stellt.

Beim Linken müssen diese Informationen zur Verfügung stehen, das geschieht dann bei:

```
target_link_libraries(...)
```
Die DLL selbst wird erst zur Laufzeit, also wenn du dein Programm startest dynamisch zu dem Programm dazugelinkt.

Gruß


----------

