IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++/CLI Discussion :

Paumé dans la création et l'utilisation de DLLs [Fait]


Sujet :

C++/CLI

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 28
    Points
    28
    Par défaut Paumé dans la création et l'utilisation de DLLs
    Bonjour,

    Je voudrais mettre au point une structure de développement sur laquelle je me casse les dents depuis deux jours. Je ne sais pas résoudre entre autres les divers problèmes de link ijw/clr/pure/pas pure (c'est une horreur)
    Voici :
    J'ai une base de code en C++ standard, agrémenté parfois de quelques utilisations de classes C++/CLI (system::string^, etc.). Je voudrais en faire une DLL utilisable dans d'autres projets (disons core.lib/core.dll; un jour il faudra que je comprenne pourquoi la génération d'une dll produit aussi un .lib)
    J'ai un projet ("solution" en visual) consituée de deux sous-projets
    -la redéfinition d'un contrôle utilisateur (UIControl)
    -le programme principal
    Ces deux projets ont besoin du code de core.dll

    Initialement, ça marchait bien :
    La dll était compilée en CLR (ni pure ni safe), décorée des divers declspec(dllexport)
    Le contrôle utilisateur était aussi en CLR (ni pure ni safe) et importait les headers en remplaçant les dllexport par dllimport, linkant avec core.lib, et utilisant #using core.dll (merci au tuto de nico-pyright)
    Le programme principal faisait de même

    Et puis un jour, le designer du programme principal s'est mis à ne plus reconnaître le contrôle utilisateur. Ce n'est pas faute d'avoir regénéré le projet, refait l'importation du contrôle dans la boîte à outil... rien à faire. Et puis finalement, en supprimant le contrôle de la boîte à outil pour le réimporter ensuite, je suis retombé sur l'erreur de chargement HRESULT machin qui apparemment vient du fait que mon usercontrol.dll n'est pas clr:pure

    J'ai donc décidé de refaire un peu ça.
    -Pour une raison que je ne m'explique pas, core.dll compile très bien en clr:pure (je croyais que le C++ et les pointeurs l'en empêcheraient). Au passage, j'ai dû supprimer les declspec(dllexport).
    -De même, mon usercontrol compile en clr:pure (en virant les dllimport des headers)
    -par contre, ça ne linke plus. Un obscur lnk2001 sur 5 ou 6 fonctions de ma dll l'en empêche. Il n'y a aucune raison pour ça, ces fonctions sont banales, et je n'ai pas dupliqué les déclarations dans différents headers, donc pas d'incohérence possible.
    -En fouillant le net, il paraît qu'il faut rajouter msvcmrt.lib, mais dans ce cas, ça n'essaye même pas de linker (mscvcmrt.lib est en ijw, incompatible clr:pure).

    J'ai essayé des tas de configurations pure/pas pure, rien n'y fait, je n'y arrive pas.

    Quelqu'un aurait-il des lumières ?

    Merci

    +
    Chacha

  2. #2
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    quelles sont les erreurs ?

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    quelles sont les erreurs ?
    error LNK2001: symbole externe non résolu
    "public: void __clrcall EXSingletonManager::destroySingletons(void)" (?destroySingletons@EXSingletonManager@@$$FQAMXXZ)

    et idem pour quelques autres fonctions d'autres classes (c'est très varié : une virtuelle, une statique, un constructeur...)

    Prenons l'exemple de cette fonction: elle n'est pas inline, elle est dans une classe. Le code est dans un .cpp, et le .h est ainsi :
    class EXSingletonManager {
    ...
    public: void destroySingletons(void);
    }...

    J'avais pensé qu'il pouvait s'agir de fonctions décorées/inlinées différemment dans le .obj en fonction des optimisations, mais j'ai bien mis les même, j'ai essayé de les désactiver, etc. Rien à faire

    +
    Chacha


    [edit]
    Tiens, ben en fait, core.dll ne génère plus de core.lib, puisque j'ai viré les dllexport qui sont incompatibles avec le clr:pure...
    J'ai aussi essayé de forcer le __clrcall devant les fonctions problématiques, mais rien ne change.
    [edit2]
    Et si je compile core.dll en clr (pas pure), c'est pareil

  4. #4
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    quand tu changes de mode de compilation, la convention d'appel par défaut change.
    Si tu fais des classes natives comme semble l'etre EXSingletonManager, tu peux essayer en définissant explicitement la convention d'appel, à stdcall par exemple

    mais peut-etre serait-il plus judicieux d'en faire des classes managées qui seront plus facilement intéropables ensuite

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    quand tu changes de mode de compilation, la convention d'appel par défaut change.
    Si tu fais des classes natives comme semble l'etre EXSingletonManager, tu peux essayer en définissant explicitement la convention d'appel, à stdcall par exemple
    Ça ne change absolument rien ! Toujours les mêmes erreurs de link sur les mêmes fonctions !

    mais peut-etre serait-il plus judicieux d'en faire des classes managées qui seront plus facilement intéropables ensuite
    Ce n'est pas mon but. Je ne veux pas réécrire en code managé toutes les classes C++ standard que j'utilise, au contraire; je veux le plus de code standard possible. En réalité, le peu de code managé dans ces classes est encapsulé par un #ifdef VISUAL ... #endif : j'utilise les types natifs quand c'est possible, en fonction du système.

    +
    Chacha

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 28
    Points
    28
    Par défaut
    Je pense à quelque chose...
    Est-ce mafaçon d'importer les headers qui ne va pas ?

    Je m'explique : dans le projet principal, même si je suis lié à ma dll, il me faut bien les headers pour utiliser les classes. Or,le compilateur va peut-être compiler certaines méthodes lors du parsing du header, et décorer différemment, ce qui donne un link "symbole non trouvé". Mais comment faire, alors, pour lui faire "lire" le header d'une classe en lui disant "ça mon coco, ce sont les déclarations d'une dll compilée, peut-être, en clr pas pure" (ce qui n'est pas le cas, mais bon) ? Il y a une astuce ?

    +
    Chacha

  7. #7
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    ce qui est sur c'est que tu ne dois pas avoir clrcall devant tes fonctions natives

    tu as un projet minimal qui reproduit l'erreur ? car je t'avouerai que je ne comprends pas trop ton histoire ...

  8. #8
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    ce qui est sur c'est que tu ne dois pas avoir clrcall devant tes fonctions natives
    tu as un projet minimal qui reproduit l'erreur ? car je t'avouerai que je ne comprends pas trop ton histoire ...
    Oui, je viens d'en faire un en vitesse. Je l'ai conçu à l'image des descriptions que j'ai fournies plus haut :
    -Un projet autonome "Core" avec un EXSingletonManager (en C++ standard) très simplifié qui crée une dll en clr
    -Un projet C++/CLI "Client" contenant un sous-projet "MyControl" et un sous-projet C++/CLI "Client", correspondant respectivement à un UIControl sous-classé et un programme principal.

    Le "MyControl" tente d'exploiter EXSingletonManager, et échoue avec la fameuse erreur de link.

    Au cas où, j'ai intégré dans le stdafx.h de quoi tester rapidement les jeux de declspec(dllexport/dllimport) (mais a priori cela est inutile)

    Pour que ça fonctionne "out of the box", je n'ai quasiment rien mis dans les options de compilation du projet, j'ai écrit en dur dans le code les chemins relatifs entre les éléments.

    Merci de ton intérêt.

    +
    Chacha

    [edit]
    Pour éviter d'insérer de potentielles erreurs de ma part, je n'ai pas spécifié les #using Core.dll et les dépendances avec Core.dll, puisque je n'ai trouvé aucune configuration correcte. C'est donc à la bonne âme qui va regarder de m'enseigner comment faire !
    Fichiers attachés Fichiers attachés

  9. #9
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 28
    Points
    28
    Par défaut
    Salut,

    As-tu regardé le code ? Je ne te cache pas que je n'ai pas beaucoup d'autres recours, alors je compte beaucoup là dessus... Comme ce n'est pas le genre de détail que l'on trouve dans un livre ou un tutorial, c'est dans ces cas là que l'on a besoin d'un expert.

    Merci d'avance,

    +
    Chacha

  10. #10
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    alors, c'est pas du tout comme ca qu'il faut faire ...

    soit ton projet "core" est une assembly qui expose les méthodes d'un objet managé, dans ce cas il faut :
    - écrire un wrapper managé dans "core" qui encapsule ton objet EXSingletonManager natif
    - référencer ce wrapper dans ton projet "client"

    soit ton projet "core" est une dll native, dans ce cas, il faut utiliser les mécanismes de C++ interop pour pouvoir acceder à ces fonctions, comme décrit dans mon tutoriel http://nico-pyright.developpez.com/t...vc2005/interop


    Une autre solution est de mixer le code natif et managé dans le meme projet, comme expliqué dans ce meme tutoriel ou dans celui la http://nico-pyright.developpez.com/t...grationcppnet/

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    alors, c'est pas du tout comme ca qu'il faut faire ...
    Ça doit être pour ça que je n'y arrive pas

    soit ton projet "core" est une assembly qui expose les méthodes d'un objet managé, dans ce cas il faut :
    - écrire un wrapper managé dans "core" qui encapsule ton objet EXSingletonManager natif
    C'est justement ce que je veux éviter: je ne vais pas refaire un wrapper par classe C++ existante.

    soit ton projet "core" est une dll native, dans ce cas, il faut utiliser les mécanismes de C++ interop pour pouvoir acceder à ces fonctions, comme décrit dans mon tutoriel http://nico-pyright.developpez.com/t...vc2005/interop
    J'ai déjà lu ce tutoriel, mais il ne répond pas vraiment à la question de l'export/import d'une classe C++ existante à partir d'une dll mixte native/managé vers un code C++ managé (et non C#!)
    En théorie, cela devrait marcher comme sur des roulettes, en pratique, j'ai mes erreur de link.

    [edit]
    j'ai l'intuition que ça marcherait si je n'étais pas obligé de faire un include des headers de la dll daans mon autre composant. Mais je n'arrive pas à utiliser des bibliothèques de type qui permettraient (?) de se passer des headers pour informer le compilo de l'existence des classes/méthodes

    +
    Chacha

  12. #12
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    dans ton projet C++/CLI, essaie simplement d'ajouter toutes tes classes native (.h et .cpp), tu buildes tout ensemble et ca marche

  13. #13
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    dans ton projet C++/CLI, essaie simplement d'ajouter toutes tes classes native (.h et .cpp), tu buildes tout ensemble et ca marche
    Oui oui, je confirme, ça marche ! C'est ce que je faisais avant.
    En réalité, je voulais simplement faire mieux. En effet, comme je vais être amené à créer plusieurs projets C++/CLI partageant la même base de code C++ natif/managé, je comptais en faire une DLL... C'est là que les ennuis ont commencé.
    Depuis quelques heures, je suis revenu à l'ancien système où mon code sera "dupliqué" entre les différents projets; tant pis, c'est moins pratique mais au moins ça fonctionne.

    Merci

    +
    Chacha

  14. #14
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    ok, j'avais pas compris.

    dans ce cas, la méthode de la dll est faisable.

    Tu crées une dll,
    tu exportes les méthodes
    tu links le .lib à ton projet c++/cli
    tu inclus les header

    et le tour est joué

  15. #15
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    ok, j'avais pas compris.

    dans ce cas, la méthode de la dll est faisable.

    Tu crées une dll,
    tu exportes les méthodes
    tu links le .lib à ton projet c++/cli
    tu inclus les header

    et le tour est joué
    Ah mais là on revient au point de départ :-)
    C'est la manipulation que j'explique dans le premier message de ce fil : je fais tout cela, mais il y a des erreurs de link, que je ne sais pas expliquer. Je suppose que cela vient du fait que je veux exporter non pas de simples fonctions, mais des classes C++. Et c'est aussi ce qu'illustre le projet minimal que j'ai posté.

  16. #16
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    non, il y a une différence, il faut lier le .lib

  17. #17
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    non, il y a une différence, il faut lier le .lib
    Nous sommes d'accord, mais tu peux constater que cela ne fonctionne pas, même dans le projet minimal !

  18. #18
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    je ne vois pas de link au .lib dans ton projet minimal
    d'autant plus que dans celui-ci, tu ne crées pas de .lib

  19. #19
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    55
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 55
    Points : 28
    Points
    28
    Par défaut
    Citation Envoyé par nico-pyright(c) Voir le message
    je ne vois pas de link au .lib dans ton projet minimal
    d'autant plus que dans celui-ci, tu ne crées pas de .lib
    Exact, mais j'ai essayé ! J'avais indiqué:
    Pour éviter d'insérer de potentielles erreurs de ma part, je n'ai pas spécifié les #using Core.dll et les dépendances avec Core.dll, puisque je n'ai trouvé aucune configuration correcte
    ...et cela concerne aussi le .lib, généré ou pas selon la configuration du projet Core (en clr:pure ou clr).
    Ne sachant comment faire, je n'ai pas surchargé la configuration du projet, mais j'ai bien sûr fait de multiples essais.

  20. #20
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Points : 16 075
    Points
    16 075
    Par défaut
    a mon avis, le problème vient de la

    il faut que tu arrives à bien exporter les méthodes et les classes et à bien lier le .lib au projet

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Création et utilisation de DLL dans mIRC
    Par ram-0000 dans le forum Réseaux
    Réponses: 0
    Dernier message: 03/04/2013, 15h13
  2. Création et utilisation de dlls dans un programme
    Par Crabe05 dans le forum Langages de programmation
    Réponses: 7
    Dernier message: 02/01/2009, 08h25
  3. [C#] Comment utiliser des dll win 32 dans un projet .NET
    Par Mickey.jet dans le forum Delphi .NET
    Réponses: 2
    Dernier message: 31/05/2005, 14h45
  4. [Eclipse 3.0] [Tomcat] problème dans la création du .war
    Par lipao17 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 12/03/2005, 14h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo