Tu peux regarder ce fichier de configuration de la bibliothèque Ogre par exemple, et regarder comment ils déclarent la macro _OgreExport selon les différents systèmes :
http://www.ogre3d.org/docs/api/html/...8h-source.html
Version imprimable
Tu peux regarder ce fichier de configuration de la bibliothèque Ogre par exemple, et regarder comment ils déclarent la macro _OgreExport selon les différents systèmes :
http://www.ogre3d.org/docs/api/html/...8h-source.html
Ca va aider, mais on y voit que GCC (version antérieure à 4) n'accepte pas de syntaxe similaire à Windows. Donc je vois pas comment on y fait des librairies partagées. Mais l'important pour moi c'est Windows.Citation:
Tu peux regarder ce fichier de configuration de la bibliothèque Ogre par exemple, et regarder comment ils déclarent la macro _OgreExport selon les différents systèmes
J'ai créé ma petite DLL, mais j'ai déjà un 1er problème: j'arrive pas à la lier au programme.
J'aimerais éviter l'édition de lien implicite (GetProcAdress) car j'ai vu dans la doc de Visual, qu'il y a la possibilité plus facile d'une édition de lien implicite.
C'est bien joli tout ça, mais je vois pas de fichier .LIB (import library) créé en même temps que la DLL, comme le suggère pourtant la doc de Visual.Citation:
To implicitly link to a DLL, executables must obtain the following from the provider of the DLL:
-A header file (.H file) containing the declarations of the exported functions and/or C++ classes.
-An import library (.LIB files) to link with. (The linker creates the import library when the DLL is built.)
-The actual DLL (.DLL file).
Executables using the DLL must include the header file containing the exported functions (or C++ classes) in each source file that contains calls to the exported functions. From a coding perspective, the function calls to the exported functions are just like any other function call.
To build the calling executable file, you must link with the import library. If you are using an external makefile, specify the file name of the import library where you list other object (.OBJ) files or libraries that you are linking with.
Des idées?
En fait, pour GCC, les fonctions sont exportées par défaut, il n'y a pas d'import/export à faire.
- GetProcAddress(), c'est EXplicite.
- Quelles sont tes options de compilation? regarde si tu n'as pas oublié d'en activer une... (genre "import library" à activer ou "doesn't produce .lib" à supprimer)
Edit: Sous visual 2005 pro, j'ai l'option Project Properties->Configuration Properties->Linker->Advanced->Import Library
Ca c'est de la réponse rapide. :D Merci
Je comprends pas, ça marche maintenant, le linker me crée bien un '.dll' ET un '.lib'.
J'avais juste vérifié dans le projet si l'option 'Import Library' était correcte, et elle l'était: "$(OutDir)/$(TargetName).lib". Je touche du bois...
Ca marche nickel avec une DLL: plus de dépendance, et pas de changement majeur dans le code source grâce à l'édition de lien implicite.
J'ai rajouté ceci dans l'entête de configuration
Je coupe les cheveux en 4, mais j'ai encore 2 petites questions:Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #if defined(__ICL) || defined(_MSC_VER) //#define MALIB_API // pour compiler/utiliser la librairie statique #ifdef MALIB_EXPORT // à définir uniquement dans le projet/makefile #define MALIB_API __declspec(dllexport) // pour compiler en DLL #else #define MALIB_API __declspec(dllimport) // pour utiliser la DLL #endif #elif defined (__GNUC) #define MALIB_API #endif
- Y a t-il un moyen de reconnaître automatiquement (avec un #ifdef ?) , si le projet compile une DLL ou une LIB? Ca m'éviterait d'avoir à modifier manuellement l'entête de configuration à chaque changement de projet.
- Il faut que l'exécutable trouve la DLL. A ma connaissance, il faut donc que la DLL soit dans le même répertoire que l'executable ou bien dans l'un des répertoires du PATH. Mais ni l'un ni l'autre n'est pratique parce que la DLL est créée dans les répertoires MaLib/release ou MaLib/debug, et parce que j'ai plusieurs programmes qui utilisent la DLL. Y'a pas un moyen plus pratique pour que les executables trouve leur bonne (debug/release) DLL? et donc sans avoir à déplacer manuellement la DLL dans chaque répertoire des exécutables.
Non. Par contre il vaut mieux définir le symbole dans les options du préprocesseur plutôt que dans le code source.Citation:
- Y a t-il un moyen de reconnaître automatiquement (avec un #ifdef ?) , si le projet compile une DLL ou une LIB? Ca m'éviterait d'avoir à modifier manuellement l'entête de configuration à chaque changement de projet.
Pas à ma connaissance. Par contre selon ton environnement, tu peux ajouter un PATH temporaire pendant l'exécution de tes projets qui requierent la DLL, ou encore faire un .bat qui copie la DLL où il faut, et exécuté automatiquement en étape de post-build.Citation:
- Il faut que l'exécutable trouve la DLL. A ma connaissance, il faut donc que la DLL soit dans le même répertoire que l'executable ou bien dans l'un des répertoires du PATH. Mais ni l'un ni l'autre n'est pratique parce que la DLL est créée dans les répertoires MaLib/release ou MaLib/debug, et parce que j'ai plusieurs programmes qui utilisent la DLL. Y'a pas un moyen plus pratique pour que les executables trouve leur bonne (debug/release) DLL? et donc sans avoir à déplacer manuellement la DLL dans chaque répertoire des exécutables.
Je m'en doutais un petit peu...
Encore merci
J'ai parlé trop vite, car finallement le problème reste entier.
La DLL n'a certes pas de dépendances, mais la librarie d'importation en a.
Je ne m'en suis pas rendu compte sur le coup car je travaille sous le même environnement (et les paths rendaient le problème transparent).
A moins de se passer de la librairie d'importation, avec des appels explicites à la DLL, je vois pas comment faire. Mais la syntaxe des appels explicites (GetProcAdresse) me paraît tellement contraignante que je désire à tout prix l'éviter.
Des idées?
Normalement ça ne devrait pas être le cas. Les bibliothèques statiques devraient être compilées dans ta DLL et ne plus t'embêter. Peut-être une option de compilation à bidouiller ?
Ca se complique.
Je cerne un peu mieux le problème, mais c'est pas encore ça
En fait j'utilise STLport pour compiler ma librairie, car d'après mes tests (qui datent certes un peu), celle-ci est plus rapide avec le compilo ICL que les STLs de VC ou de GCC pour les calculs mathématiques (en particulier sur les nombres complexes). Bref, j'utilise une librairie (statique ou dynamique, c'est selon) pour STLport.
Je me mets dans la peau d'un utilisateur lambda, sans STLport mais utilisant la STL intégrée à Visual.Je réussis à lier mon programme avec ma DLL, mais son lancement m'annonce qu'il lui faut impérativement la DLL de STLport. Donc il y a dorénavant une dépendance dynamique (alors que la dépendance était auparavant statique avec les LIB)
En plus, STLport à un comportement inhabituel pour lier la librairie (statique ou dynamique). Il n'est pas besoin de rajouter la dépendance dans l'édition de liens du projet comme d'hab.
En fait il y a a qq part dans un '.h' de STLport une instruction pour importer la bonne librairie. (j'ai pas encore dénicher l'endroit dans le code. Vu que je connais pas l'instruction, c'est pas facile à trouver)
Ca me laisse penser qu'il existe bien une possibilité, pour faire en sorte que le code C++ sache si le compilo est en mode statique ou dynamique)
J'ai raison?
Des pistes?
Donc, au final, dans le programme, std::complex vaudra des choses différentes selon là où on se trouve ? C'est une violation de l'ODR, ce qui est un comportement indéfini. En pratique, pour ce genre de manip, il faut surtout éviter par dessus tout que des variables de tous ces types soient passé entre les deux bouts du programme.Citation:
Envoyé par Charlemagne
Oui, les DLL ne sont pas linkées... Puisque c'est tout leur intérêt...Citation:
Envoyé par Charlemagne
Pourquoi ne pas utiliser des libs statiques ? Il me semble que dans les options de projet d'une bibliothèque statique visual C++, tu as un onglet nommé Librerian qui te permet d'aggréger une autre bibliothèque statique avec la tienne. Il me semble que j'ai déjà eu des surprises avec cet onglet, mais je ne sais plus lesquelles, et c'était à un moment où j'avais pas eu le temps de prendre le temps de comprendre.
Regarde un truc genre #pragma comment (lib:...)Citation:
Envoyé par Charlemagne
Souvent, le compilatuer définira des macros préprocesseur (genre DLL).Citation:
Envoyé par Charlemagne
Il est tard, j'ai pas encore essayé tes propositions, mais ca devrait m'avancer sérieusement.
Je n'avais pas pensé à ce problème éventuel. Ca devrait pas être un problème pour les complexes dont le code est normalement intégralement dans les '.h', à moins d'instanciations explicites dans la librairie STL. Mais la remarque est pertinente. Y'a surement quelques fonctions instanciées (je pense aux entrées-sorties), mais pour l'instant j'ai pas vu de doubles définitions lors de l'édition de lien avec le programme utilisateur.Citation:
Donc, au final, dans le programme, std::complex vaudra des choses différentes selon là où on se trouve ? C'est une violation de l'ODR, ce qui est un comportement indéfini. En pratique, pour ce genre de manip, il faut surtout éviter par dessus tout que des variables de tous ces types soient passé entre les deux bouts du programme.
Le problème sera peut-être plus flagrant avec ta proposition un peu plus loin d'aggréger des libs statiques.
Que faire si y'a des doublets lors de l'édition de lien?
Ca aussi ça peut m'intéresser, si y'a pas de problème de doublets.Citation:
Pourquoi ne pas utiliser des libs statiques ? Il me semble que dans les options de projet d'une bibliothèque statique visual C++, tu as un onglet nommé Librerian qui te permet d'aggréger une autre bibliothèque statique avec la tienne. Il me semble que j'ai déjà eu des surprises avec cet onglet, mais je ne sais plus lesquelles, et c'était à un moment où j'avais pas eu le temps de prendre le temps de comprendre.
Je connais pas cette posibilité de fusionner des libs. Si ça marche, je l'adopte.
C'est l'option "additional dependencies" dans Liberian?
Je vais tâcher de voir ça demain.Citation:
Regarde un truc genre #pragma comment (lib:...)
Souvent, le compilatuer définira des macros préprocesseur (genre DLL).
Mes essais ne sont pas concluants, et donc j'ai encore des questions.
1)
J'ai pas trouvé le moyen de fusionner/aggréger des libs statiques. J'ai bien essayé l'option 'additional dependencies' dans l'onglet Liberian, pour inclure la librairie statique de STLport. Mais lors de l'édition de lien du programme utilisateur, ma librairie impose encore la dépendance envers la lib statique de STLport.
2)
C'est bien "#pragma comment (lib: )" pour importer des libs dans le code source.
Et j'ai effectivement trouvé la macro _DLL, définie par Visual lorsque le code généré est en "Multithreaded DLL" (/MD, /MDd).
Mais cette macro ne permet pas de savoir si le compilo génère ou non une DLL. Car il est tout-à-fait possible de faire une librairie statique en MD !!!, comme il est possible de faire une librairie dynamique en MT/ML !!!
Je pense avoir une idée de ce qu'est la géneration single/muti threaded (ML/MT), mais je comprends donc plus à quoi sert le multithreaded DLL.
Pour ta question 2, c'est en fait à quel runtime on va lier ta bibliothèque. Ce runtime contient en gros la bibliothèque standard, et on peut l'avoir en version statique ou dynamique, en version monothread - plus rapide - ou multithread - quand on utilise les threads :aie: -
Désolé, je ne peux pas vraiment t'aider, puisque comme je l'ai dit, je n'ai jamais vraiment utilisé ce truc. Peut-être permet-il juste d'éviter à l'utilisateur de devoir spécifier dans son projet qu'il a besoin de l'autre bibliothèque, mais ne permet pas d'éviter qu'elle soit fournie ?Citation:
Envoyé par Charlemagne
Le dernier conseil que je peux donner, c'est d'utiliser dumpbin.exe(http://msdn2.microsoft.com/fr-fr/library/756as972.aspx) pour deboguer les symboles présents dans une lib.