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++ Discussion :

Aide pour création d'une DLL


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 46
    Points
    46
    Par défaut Aide pour création d'une DLL
    Bonjour,

    Je cherche à créer une DLL dans VS me permettant d'accéder à une API écrite en C++ dans Delphi.
    Mon problème est que le C++ est loin derrière moi et qu'après 10 lignes écrites déjà une erreur que je ne comprend pas

    Voici donc cette erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1>RimageAPI.obj : error LNK2019: symbole externe non résolu "__declspec(dllimport) public: static class Rimage::Rapid::Api::SingleConnectionSession * __cdecl Rimage::Rapid::Api::SingleConnectionSession::GetInstance(void)" (__imp_?GetInstance@SingleConnectionSession@Api@Rapid@Rimage@@SAPAV1234@XZ) référencé dans la fonction _RimageConnect
    Et mes fichiers :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    // RimageAPI.h*: fichier d'en-tête principal pour la DLL RimageAPI
    //
     
    #pragma once
    #include "afxwin.h"
    #include <RapidApiInclude.h>
     
    using namespace Rimage::Rapid::Api;
     
    #ifndef __AFXWIN_H__
    	#error "incluez 'stdafx.h' avant d'inclure ce fichier pour PCH"
    #endif
     
    #include "resource.h"		// symboles principaux
     
     
    // CRimageAPIApp
    // Consultez RimageAPI.cpp pour l'implémentation de cette classe
    //
     
    class CRimageAPIApp : public CWinApp
    {
    public:
    	CRimageAPIApp();
     
    // Substitutions
    public:
    	virtual BOOL InitInstance();
     
    	DECLARE_MESSAGE_MAP()
    };
     
    extern "C" __declspec(dllexport) BOOL RimageInit();
    extern "C" __declspec(dllexport) BOOL RimageConnect(const LPCTSTR client, const LPCTSTR host = NULL, const LPCTSTR port = NULL);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    // RimageAPI.cpp*: définit les fonctions d'initialisation pour la DLL.
    //
     
    #include "stdafx.h"
    #include "RimageAPI.h"
     
    #ifdef _DEBUG
    #define new DEBUG_NEW
    #endif
     
    // CRimageAPIApp
     
    BEGIN_MESSAGE_MAP(CRimageAPIApp, CWinApp)
    END_MESSAGE_MAP()
     
     
    // construction CRimageAPIApp
     
    CRimageAPIApp::CRimageAPIApp()
    {
    	// TODO*: ajoutez ici du code de construction,
    	// Placez toutes les initialisations significatives dans InitInstance
    }
     
     
    // Seul et unique objet CRimageAPIApp
     
    CRimageAPIApp theApp;
     
     
    // initialisation de CRimageAPIApp
     
    BOOL CRimageAPIApp::InitInstance()
    {
    	CWinApp::InitInstance();
     
    	return TRUE;
    }
     
    BOOL RimageInit()
    {
    	//SingleConnectionSession* pConnSession = SingleConnectionSession::GetInstance();
    	//pConnSession->SetDefaultJobListener();
     
    	return TRUE;
    }
     
     
    BOOL RimageConnect(const LPCTSTR client, const LPCTSTR host, const LPCTSTR port)
    {
    	return TRUE;
    	SingleConnectionSession* pConnSession = SingleConnectionSession::GetInstance();
    	//if(!pConnSession->IsConnected())
    	//{
    	//	pConnSession->Connect(client, host, port);
    	//	return TRUE;
    	//}
    	//else // if already connected
    	//{
    		//Connection* pConection = pConnSession->GetConnection();
    		//if(_tcsicmp(pConection->GetHost(), host)!=0)
    		//{
    		//	// Disconnect the old one, make a new connection
    		//	pConnSession->Disconnect();
    		//	pConnSession->Connect(client, host, port);
    		//	return TRUE;
    		//}
    		//else
    		//{
    		//	return FALSE;
    		//}
    	//}
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ; RimageAPI.def : déclare les paramètres de module pour la DLL.
     
    LIBRARY      "RimageAPI"
     
    EXPORTS
        ; Les exportations explicites peuvent être placées ici
        RimageInit	@1
        RimageConnect	@2
    Comme vous pouvez le pouvoir il ne reste qu'une ligne qui ne soit pas commentée... (ligne 52 du .cpp)
    Il semble que les objets que j'utilise soient mal référencés pourtant VS arrive à accéder aux définitions.
    Bref si certains d'entre vous peuvent m'aiguillez

    Merci

  2. #2
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2010
    Messages
    517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Santé

    Informations forums :
    Inscription : Avril 2010
    Messages : 517
    Points : 718
    Points
    718
    Par défaut
    Salut,

    C'est un problème d'édition de liens.

    Je suppose que tu utilises une bibliothèque externe non? Est-ce que tu l'as ajouté à ta solution?

  3. #3
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 629
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 629
    Points : 30 692
    Points
    30 692
    Par défaut
    Salut,

    Ce qu'il faut savoir concernant les dll, c'est que tu as besoin de deux déclarations différentes en fonction de si tu compiles ta dll ou de si tu essayes de l'utiliser.

    Lorsque tu la compiles, tu as en effet besoin d'un __declspec(dllexport) afin d'indiquer qu'un symbole doit être exporté, mais tu as besoin d'un __declspec(dllimport) lorsque tu l'utilises, afin d'indiquer que le symbole doit être importé.

    L'une des solutions consiste alors à "dédoubler" tes fichiers d'en-tête sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    // RimageAPI.h*: fichier d'en-tête principal pour la DLL RimageAPI
    //
     
    #pragma once
    #include "afxwin.h"
    #include <RapidApiInclude.h>
     
    using namespace Rimage::Rapid::Api;
     
    #ifndef __AFXWIN_H__
    	#error "incluez 'stdafx.h' avant d'inclure ce fichier pour PCH"
    #endif
     
    #include "resource.h"		// symboles principaux
     
     
    // CRimageAPIApp
    // Consultez RimageAPI.cpp pour l'implémentation de cette classe
    //
     
    class CRimageAPIApp : public CWinApp
    {
    public:
    	CRimageAPIApp();
     
    // Substitutions
    public:
    	virtual BOOL InitInstance();
     
    	DECLARE_MESSAGE_MAP()
    };
     
    extern "C" __declspec(dllexport) BOOL RimageInit();
    extern "C" __declspec(dllexport) BOOL RimageConnect(const LPCTSTR client, const LPCTSTR host = NULL, const LPCTSTR port = NULL);
    que tu utiliseras lorsque tu compile ta dll et sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    // RimageAPI.h*: fichier d'en-tête principal pour la DLL RimageAPI
    //
     
    #pragma once
    #include "afxwin.h"
    #include <RapidApiInclude.h>
     
    using namespace Rimage::Rapid::Api;
     
    #ifndef __AFXWIN_H__
    	#error "incluez 'stdafx.h' avant d'inclure ce fichier pour PCH"
    #endif
     
    #include "resource.h"		// symboles principaux
     
     
    // CRimageAPIApp
    // Consultez RimageAPI.cpp pour l'implémentation de cette classe
    //
     
    class CRimageAPIApp : public CWinApp
    {
    public:
    	CRimageAPIApp();
     
    // Substitutions
    public:
    	virtual BOOL InitInstance();
     
    	DECLARE_MESSAGE_MAP()
    };
     
    extern "C" __declspec(dllimport) BOOL RimageInit();
    extern "C" __declspec(dllimport) BOOL RimageConnect(const LPCTSTR client, const LPCTSTR host = NULL, const LPCTSTR port = NULL);
    lorsque tu l'utilises (c'est donc cette version du fichier d'en-tête que tu devras fournir aux utilisateurs finaux de ta dll)

    Mais bon, tu comprendra vite que ce n'est pas efficace, car cela t'oblige à modifier les deux fichiers à chaque fois.

    L'autre solution est de choisir la bonne valeur en fonction de symboles que tu pourrais passer au compilateur et de profiter avantageusement de ce qu'on appelle la compilation conditionnelle.

    L'idée consiste alors à écrire un code proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #if defined (SHARED) // on n'a besoin de l'API que dans le cas d'une bibliothèque partagée (shared library)
    #    if defined (_WIN32) // et uniquement sous windows (sous windows, les bibliothèques partagées portent le nom de dll)
    #        ifdefined (BUILD_MYDLL) // un nom unique pour spécifier qu'on compile cette dll en particulier
    #            define MYDLL_API __declspec(dllexport)
    #        else // si on la compile pas, on l'utilise
    #            define MYDLL_API __declspec(dllimport)
    #        endif
    #    else  // si l'on n'est pas sous windows, on n'a pas besoin de ca
    #        define MYDLL_API
    #    endif
    #else // si on compile une bibliothèque statique, on n'a pas besoin de ca
    #    define MYDLL_API
    #endif
    où MYDLL_API est un nom que tu choisi toi-même qui ne sera utilisé que pour la bibliothèque en question (afin d'éviter les problèmes si tu viens à essayer de compiler une dll qui en utiliserait une autre)

    Tu mettrais ce code dans un fichier d'en-tête spécial, par exemple dans myDll_api.h (nom à adapter à tes besoin, évidemment) que tu pourrais inclure dans chaque fichier qui a besoin de la définition du symbole "MYDLL_API".

    Tu pourrais donc transformer ton fichier d'en-tête sous la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    // RimageAPI.h*: fichier d'en-tête principal pour la DLL RimageAPI
    //
     
    #pragma once
    #include "afxwin.h"
    #include <RapidApiInclude.h>
     
    using namespace Rimage::Rapid::Api;
     
    #ifndef __AFXWIN_H__
    	#error "incluez 'stdafx.h' avant d'inclure ce fichier pour PCH"
    #endif
     
    #include "resource.h"		// symboles principaux
    #include "myDll_api.h"
     
    // CRimageAPIApp
    // Consultez RimageAPI.cpp pour l'implémentation de cette classe
    //
     
    class CRimageAPIApp : public CWinApp
    {
    public:
    	CRimageAPIApp();
     
    // Substitutions
    public:
    	virtual BOOL InitInstance();
     
    	DECLARE_MESSAGE_MAP()
    };
     
    extern "C" MYDLL_API BOOL RimageInit();
    extern "C" MYDLL_API BOOL RimageConnect(const LPCTSTR client, const LPCTSTR host = NULL, const LPCTSTR port = NULL);
    et "tout ce qu'il te resterait à faire" c'est de définir, dans les options de compilations de ton projet, les symboles SHARED et BUILD_MYDLL (ou non) en fonction de tes besoins.

    L'idée est que, lorsque la ligne de commande de compilation prendra une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <compilateur> /DSHARED /DBUILD_MYDLL -c fichier.cpp
    MYDLL_API sera définie à __declspec(dllexport), parce que tu compile ta dll;
    Que, lorsqu'elle prendra la forme de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <compilateur> /DSHARED-c fichier.cpp
    , MYDLL_API sera définie à __declspec(dllimport) parce que tu utilises ta dll et que, si /DSHARED n'apparait pas, MYDLL_API sera défini à une valeur vide, parce que tu compile une version statique de ta bibliothèque et que tu n'as donc pas besoin d'exporter ou d'importer les symboles (il en ira de même si tu décides de compiler ton projet sous linux )

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 74
    Points : 46
    Points
    46
    Par défaut
    Citation Envoyé par darkman19320 Voir le message
    Salut,

    C'est un problème d'édition de liens.

    Je suppose que tu utilises une bibliothèque externe non? Est-ce que tu l'as ajouté à ta solution?
    Merci après de longues heures j'ai enfin trouvé.
    Comme dit ci-dessus c'était un problème de bibliothèque.
    Du coup il m'a fallu renseigner :

    C/C++ >> Général >> Autres répertoires include
    Éditeur de liens >> Général >> Répertoires de bibliothèques supplémentaires
    Éditeur de liens >> Entrée >> Dépendances supplémentaires

    Merci pour votre aide.

    Maintenant je cherche à créer des callbacks dans ma dll pour faire passer les callbacks C++ de la DLL à laquelle je me connecte...
    Du coup vous risquez d'avoir très vite de mes nouvelles

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2010] Aide pour Création d'une BD (Rapport Journalier exploitation minière)
    Par saphir5 dans le forum Modélisation
    Réponses: 2
    Dernier message: 09/06/2013, 13h06
  2. [XL-2000] Aide pour création d'une macro complexe
    Par dybmans dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 26/10/2010, 12h38
  3. Réponses: 3
    Dernier message: 23/01/2010, 12h23
  4. Réponses: 2
    Dernier message: 22/07/2009, 22h36
  5. Aide pour création d'une page en ASP
    Par jj6401 dans le forum ASP
    Réponses: 8
    Dernier message: 06/03/2009, 11h04

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