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 :

Erreur de link dll


Sujet :

C++

  1. #1
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut Erreur de link dll
    Bonjour,

    n'ayant pas trouvé de réponse à ma question (j'espère ne pas être passé à côté), je me permet d'ouvrir un nouveau topic.

    Mon problème est le suivant:

    J'utilise une dll open source que j'ai légèrement modifiée et compilée. Jusqu'ici, aucun problème.

    Je l'importe de façon explicite dans mon programme via LoadLibrary et GetProcAdress.

    J'ai bien inclus le .h de la dll dans mon source.

    Lors de l'édition de lien, une erreur (entre autres) survient:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    unresolved external symbol "__declspec(dllimport) public: unsigned long __thiscall IntelLaptopGamingTDKInterface::GetSecBatteryLifeTimeRemaining(void)" (__imp_?GetSecBatteryLifeTimeRemaining@IntelLaptopGamingTDKInterface@@QAEKXZ) referenced in function "public: void __thiscall cBattery::Refresh(long)" (?Refresh@cBattery@@QAEXJ@Z)	Exec.lib
    Il me semble que lorsque l'on utilise la méthode explicite d'importation (LoadLibrary + ....) il n'est pas nécessaire d'utiliser le .lib fournit avec la dll.

    En vous remerciant d'avance pour votre réponse

    p.s: je dois absolument utiliser le méthode explicite cas je charge différentes dll en fonction du contexte (XP, VISTA).

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Le problème, c'est qu'apparemment ta méthode cBattery::Refresh() fait un appel implicite à cette fonction...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  3. #3
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    merci pour ta réponse rapide.

    Cependant étant débutant pourrais tu m'en dire un peu plus et me donner une piste pour résoudre ce problème?

    merci

    p.s: En fait j'ai bien essayé avec GetProcAddress mais la dll s'utiliserait ainsi:

    appel de GetTDKInterface() fonction statique qui renvoie un singleton de la classe définie dans la dll.

    puis appel de la méthode GetPercentBatteryLife() par exemple pour récupérer la valeur désirée.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Pas trop, je ne connais pas assez tes contraintes ni comment marche cBattery, ni ton chargement initial... (notamment, tu fais GetProcAddress() sur quoi exactement?)
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  5. #5
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    Si on charge une dll dynamiquement, on ne devrait pas avoir une erreur de link sur une fonction de la dll tout au plus une erreur à l'execution ?

  6. #6
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Sorry je vais essayer de te donner quelques éléments.

    voici un bout de code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    if(GetOSVersion() < OS_WIN32_WINDOWS_VISTA)
    		mDllHAndler=LoadLibrary("IntelLaptopGamingXp.dll");
    	else
    		mDllHAndler=LoadLibrary("IntelLaptopGaming.dll");
    	if(mDllHAndler)
    	{
    		DllImported_GetTDKInterface = (Type_GetTDKInterface)GetProcAddress(mDllHAndler,"?GetTDKInterface@IntelLaptopGamingTDKInterface@@SIPAV1@XZ");
     
    		if(DllImported_GetTDKInterface)
    			mHardInfo = DllImported_GetTDKInterface();
    	}
    Ici, je charge la dll avec LoadLibrary(). Ensuite je récupère la méthode GetTDKInterface de la dll avec GetProcAddress() et l'appelle afin de récupérer une instance de la classe de ma dll (nommons la 'monInstance').

    cBattery est une classe qui rafraichit les infos sur la batterie d'un pc portable. Pour cela, ca méthode Refresh() est appelée régulièrement. C'est par exemple dans celle ci que je vais appeler les méthodes de la dll à partir de monInstance.

    La classe de la dll met a dispo plusieurs méthodes de gestion de la batterie, wifi, ....

    Voilà, si besoin de plus d'infos, je suis à disposition

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Il faut que toutes les méthodes publiques de la classe en question soient virtuelles, sans exception (enfin, certaines peuvent être inline, mais je le déconseille).

    C'est ainsi que fait COM.
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  8. #8
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    ouki merci, je vais tester ca

  9. #9
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Et bien, ça ne corrige pas mon problème :s

    J'ai regardé dans pas mal de forums et nulle part je n'ai trouvé ce problème.

    En général, une fonction de la dll crée une instance de la classe qui est renvoyée. Cette instance est ensuite utilisée pour appeler les méthodes directement.

    Ce que je ne comprends pas c'est qu'en ayant inclus le .h, j'ai une erreur de link :/

    voici le .h:

    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    /*
    Copyright (c) 2006, Intel Corporation.
     
    This Intel Laptop Gaming TDK ("Software") is furnished under license and may 
    only be used or copied in accordance with the terms of that license. No license, 
    express or implied, by estoppel or otherwise, to any intellectual property rights 
    is granted by this document. The Software is subject to change without notice, 
    and should not be construed as a commitment by Intel Corporation to market, 
    license, sell or support any product or technology. Unless otherwise provided 
    for in the license under which this Software is provided, the Software is 
    provided AS IS, with no warranties of any kind, express or implied. 
    Except as expressly permitted by the Software license, neither Intel Corporation 
    nor its suppliers assumes any responsibility or liability for any errors or 
    inaccuracies that may appear herein. Except as expressly permitted by the 
    Software license, no part of the Software may be reproduced, stored in a 
    retrieval system, transmitted in any form, or distributed by any means 
    without the express written consent of Intel Corporation.
    */
     
    /**
    * This is a higher level class which provides access to classes defined 
    * for individual devices. This class is exposed to user and control 
    * creation and deletion of objects as needed
    */
     
    #ifndef INTELGAMINGTDKAPI_H
    #define INTELGAMINGTDKAPI_H
     
    //#define MADLL_EXPORTS
     
    #ifdef MADLL_EXPORTS
    #define LINKDLL __declspec(dllexport)
    #pragma message("Building DLL" )
    #else
    #define LINKDLL __declspec(dllimport)
    #pragma message("Importing DLL" )
    #endif 
     
    #include "ILGdefines.h"
    #include "ILGAbstractEventInfo.h"
     
    class PowerInfo;
    class ProcessorInfo;
    class NetworkInfo;
    class DisplayInfo;
    class BandwidthInfo;
     
    #ifdef __cplusplus    // If used by C++ code, 
    #pragma message("using extern 'C' instruction" )
    extern "C" {          // we need to export the C interface
    #endif
     
    class LINKDLL IntelLaptopGamingTDKInterface
    {
    private:
    	PowerInfo* m_PowerInfo;
    	NetworkInfo* m_NetworkInfo;
    	DisplayInfo* m_DisplayInfo;
    	ProcessorInfo* m_ProcessorInfo;
    	BandwidthInfo* m_BandwidthInfo;
    	static bool bInitialize;
    	static bool m_bVista;
    	static bool m_bx64;
    protected:
    	IntelLaptopGamingTDKInterface();
    	static IntelLaptopGamingTDKInterface* Interface;
     
    public:
     
    	/**
            * Static function to get instance of pointer to IntelLaptopGamingTDKInterface 
            * class
            */ 
    	static IntelLaptopGamingTDKInterface* GetTDKInterface();
     
    	/**
            * Standard destructor
            */
    	~IntelLaptopGamingTDKInterface();
     
    	// Properties
     
    	/**
            * Start the threaded model offered by the TDK to get updates to
            * specified events/properties. 
            * This function takes in pointer to 'Notifiable' class implemented
            * by the client to call back into caller site.
            */
    	void RegisterEventObserver(int event, Notifiable* m_pNot, int WatchForValue = -1, int UpdateFreq = 2000);
     
    	/** 
            * Halt the threaded model offered by the TDK. 
            */
    	void UnregisterEventObserver(int event);
     
     
    	/**
            * Checks if the current system is a laptop
            */
    	virtual bool IsLaptop();
     
    	/**
            * Get current power source
            */
    	PowerSource GetPowerSrc();
     
    	/**
            * Get percent battery life left
            */
    	int GetPercentBatteryLife();
     
    	/**
            * Get battery life time remaining
            */
    	unsigned long GetSecBatteryLifeTimeRemaining();
     
    	/**
            * Get current power scheme of the system
            */
    	PowerScheme GetCurrentPowerScheme();
     
    	/**
            * Set power scheme for the system
            */
    	bool SetCurrentPowerScheme(PowerScheme new_scheme);
     
     
    	/**
            * Get 802.11 signal strength
            */
    	int Get80211SignalStrength();
     
    	/**
            * Is wireless adapter connected to network
            */
    	bool IsWirelessAdapterConnected();
     
    	/**
            * Is wireless adapter enabled
            */
    	bool IsWirelessAdapterEnabled();
     
    	/**
            * Get list of all adapters on the system
            */
    	char** GetAllNetworkAdapters(int* cnt);
     
    	/**
            * Get IP address
            */
    	char** GetIPAddresses(int* cnt);
     
    	/**
            *
            */
    	char* GetConnectedAdapter(char* adapterName,int bufferSize);
    	void ReleaseMem(unsigned char* ptr);
     
    	/**
            * Get current Tx Rate in bytes/sec 
            */
    	unsigned long GetCurrentTxRate();
     
    	/**
            * Get current Rx Rate in bytes/sec
            */
    	unsigned long GetCurrentRxRate();
     
    	/**
            * Get Tx + Rx rate in bytes/sec
            */
    	unsigned long GetTotalTxRxRate();
     
     
    	/**
            * Get current dislay resolution. Returned as struct
            */
    	Resolution GetDisplayResolution();
     
    	/**
            * Set display resolution e.g. 1024x768
            */
    	bool SetDisplayResolution(Resolution res);
     
    	/**
            * Set color depth for display properties
            */
    	bool SetDisplayColorDepth(int depth);
     
    	/**
            * Set display screen brightness
            */
    	bool SetDisplayScreenBrightness(float brightness);
     
    	/**
            * Get display color depth
            */
    	int GetDisplayColorDepth();
     
    	/**
            * Get display screen brightness
            */
    	float GetDisplayScreenBrightness();
     
    	/**
            * Restore original screen brightness
            */
    	bool RestoreOriginalBrightness();
     
     
    	/**
            * Get number of core on per physical processor
            */
    	unsigned int GetNumCoresPerProcessor();
     
    	/**
            * Get total number of processors as seen by OS
            */
    	unsigned int GetNumProcessors();
     
    	/**
            * Get number of active threads for a process
            */
    	int GetNumActiveThreadsForProcess(const char* ProcessName);
     
    	/**
            * Get current CPU utilization
            */
    	int GetCurrentCPUUtilization(int CpuNum = -1);
     
    	/**
            * Get current processor frequency
            */
    	unsigned long GetCurrentCPUFrequency();
     
    	/**
            * Get maximum frequency
            */
    	unsigned long GetMaxCPUFrequency();
    };
     
    #ifdef __cplusplus
    }
    #endif
     
    typedef IntelLaptopGamingTDKInterface*	(*Type_GetTDKInterface)();
    /*typedef bool							(*Type_IsLaptop)();
    typedef char*							(*Type_GetConnectedAdapter)(char*, int);
    typedef bool							(*Type_IsWirelessAdapterConnected)();
    typedef int								(*Type_Get80211SignalStrength)();
    typedef	int								(*Type_GetPercentBatteryLife)();
    typedef	PowerSource						(*Type_GetPowerSrc)();
    typedef	unsigned long					(*Type_GetSecBatteryLifeTimeRemaining)();
    */
    #endif INTELGAMINGTDKAPI_H
    Et l'utilisation que j'en fais:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    if(GetOSVersion() < OS_WIN32_WINDOWS_VISTA)
    		mDllHAndler=LoadLibrary("IntelLaptopGamingXp.dll");
    	else
    		mDllHAndler=LoadLibrary("IntelLaptopGaming.dll");
    	if(mDllHAndler)
    	{
    		DllImported_GetTDKInterface = (Type_GetTDKInterface)GetProcAddress(mDllHAndler,"?GetTDKInterface@IntelLaptopGamingTDKInterface@@SIPAV1@XZ");
     
    		if(DllImported_GetTDKInterface)
    			mHardInfo = DllImported_GetTDKInterface();
     
    		mHardInfo->IsLaptop();
    	}
    Si j'enlève mHardInfo->IsLaptop(); pas de souci. Par contre, si cette ligne est présente, une erreur est levée au link:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Error	1	error LNK2001: unresolved external symbol "public: virtual bool __thiscall IntelLaptopGamingTDKInterface::IsLaptop(void)" (?IsLaptop@IntelLaptopGamingTDKInterface@@UAE_NXZ)	Exec.lib
    Alors, ais-je oublié quelque chose .... je ne vois vraiment pas quoi !

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Franchement, je ne sais pas quoi répondre.
    Sous COM, pour éviter cela, on passe par une classe abstraite ne contenant que des fonctions virtuelles pures (et le client ne voit aucun header concernant les classes qui en héritent: Il ne connait que la classe abstraite).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  11. #11
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    ok, merci quand même

    Je vais essayer de trouver une solution

    Si quelqu'un a une solution, je suis preneur !

  12. #12
    Futur Membre du Club
    Profil pro
    Étudiant
    Inscrit en
    Septembre 2007
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2007
    Messages : 13
    Points : 8
    Points
    8
    Par défaut
    Bon, j'ai contourné le problème avec un petit bidouillage:

    J'ai implémenté et exporté mes propres fonctions dans la dll qui font elles même appels aux méthodes désirées de la classe de la dll.

    En gros, chacune de mes fonctions récupère le singleton et appelle la méthode désirée.

    Voili voilou

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

Discussions similaires

  1. Erreur de LINK DLL
    Par ZeNoob dans le forum Visual C++
    Réponses: 4
    Dernier message: 22/05/2013, 12h08
  2. [DLL]Erreur de link quand passage par reference
    Par Yeti_in dans le forum C++
    Réponses: 2
    Dernier message: 19/11/2008, 02h47
  3. Réponses: 1
    Dernier message: 02/11/2006, 20h09
  4. Erreur de link entre dlls
    Par Spartan03 dans le forum C++
    Réponses: 1
    Dernier message: 16/08/2006, 19h48
  5. Erreur de link a la creation d'une dll
    Par drcd dans le forum MFC
    Réponses: 12
    Dernier message: 29/05/2006, 15h13

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