web-dev-qa-db-fra.com

À propos de la liaison dll incohérente

Comment puis-je supprimer cet avertissement de lien? Vous pouvez voir le segment de code qui provoque cet avertissement.

static AFX_EXTENSION_MODULE GuiCtrlsDLL = { NULL, NULL };
//bla bla
// Exported DLL initialization is run in context of running application
    extern "C" void WINAPI InitGuiCtrlsDLL()
    {
     // create a new CDynLinkLibrary for this app
      new CDynLinkLibrary(GuiCtrlsDLL);
     // nothing more to do
    }

avertissement C4273: "InitGuiCtrlsDLL": liaison de DLL non cohérente

J'ai également des définitions d'exportation et d'importation, comme:

#ifdef _GUICTRLS
   #define GUI_CTRLS_EXPORT __declspec(dllexport)
#else
   #define GUI_CTRLS_EXPORT  __declspec(dllimport)
#endif
40
baris.aydinoz

Les possibilités sont multiples:

1) static AFX_EXTENSION_MODULE GuiCtrlsDLL = { NULL, NULL };

Vous utilisez AFX_EXTENSION_MODULE. Cela signifie que vous implémentez une DLL d'extension MFC. Pour de telles DLL d'extension, vous devez définir le préprocesseur _AFXEXT. Définissez cela dans les paramètres du compilateur C++ de votre projet Visual C++

voir:

Comment utiliser _declspec (dllexport) dans une DLL d'extension MFC: http://support.Microsoft.com/kb/128199

(Actuellement, je ne peux pas poster plus d'un lien car ma réputation est inférieure à 10. J'ajouterai 2 liens plus importants plus tard. Donc si c'est la solution, marquez-le comme réponse pour accélérer le processus;))

Comme promis, voici les deux liens:

Structure AFX_EXTENSION_MODULE: http://msdn.Microsoft.com/en-us/library/sxfyk0zk.aspx

TN033: DLL Version de MFC: http://msdn.Microsoft.com/en-us/library/hw85e4bb.aspx

2) Il est probable que vous ayez une définition/déclaration en double.

21
Gökhan Akca

Le but des instructions de préprocesseur:

#ifdef _GUICTRLS 
   #define GUI_CTRLS_EXPORT __declspec(dllexport) 
#else 
   #define GUI_CTRLS_EXPORT  __declspec(dllimport) 
#endif 

consiste à s'assurer que le fichier d'en-tête déclare la classe ou la fonction en tant que __declspec (dllexport) dans le .dll où il est défini, et en tant que __declspec (dllimport) pour tout autre .dll qui pourrait vouloir l'utiliser.

Pour que cela fonctionne, _GUICTRLS doit être défini lors de la compilation du .dll d'exportation, et non défini pour tout autre .dll. En règle générale, vous vous attendez à ce que _GUICTRLS soit défini dans les propriétés du projet, sous C/C++ -> Préprocesseur -> Définitions du préprocesseur.

L'erreur de compilation que vous voyez se produit généralement parce que _GUICTRLS n'est pas défini pour le projet qui effectue l'exportation, ou il est défini pour plusieurs projets, résultant généralement de la coupe d'un collage d'un projet à un autre. Vous verrez également cela si _GUICTRLS est défini dans un fichier d'en-tête qui est inclus dans plusieurs projets.

40
Eric Thompson

Cet avertissement est généralement provoqué par une définition en double d'une fonction avec une utilisation différente de dllimport. Êtes-vous sûr de ne pas l'avoir fait?

2
Matteo Italia

[CMake liaison dll incohérente]

J'ai rencontré le problème + la solution suivante avec le __declspec (dllexport) + __declspec (dllimport):

# # #CMakeLists.txt
add_defintions(-DMYLIB=1)
# The above was the solution...
#    (MYLIB is used in the standard ifdef + define MYLIB_EXPORT syntax)
#  Below: seems to get overruled by other directory's headers: 
set_source_files_properties(  file1.h  file2.h  COMPILE_FLAGS "-DMYLIB=1") 

C'était ennuyeux car un certain nombre de sources disent utiliser la commande 'set source file properties' pour obtenir une meilleure granularité mais le document n'est pas clair sur ce qui arrive aux déclarations de file1.h lorsqu'elles sont incluses à partir d'un répertoire différent ... il vaut mieux s'en tenir à add_definitions( -DMYLIB=1 ) pour l'instant!

Pour attraper ce problème: dans votre fichier Foo.cpp:

#include "export.h"
#if defined(MYLIB)
#if defined(OTHERLIB)
  static_assert(0,"error, check your definitions!");
  // OTHER depends on MY; can't have both of these flags being set!
#endif
#endif
struct  OTHER_EXPORT  foo 
{ 
};
1
peter karasev

En plus de lire le message d'avertissement, faites attention à l'endroit où il se produit si vous avez plusieurs projets dans le cadre d'un espace de travail.

J'ai perdu du temps à chercher un problème dans mon DLL qui se compilait et se liait correctement. L'espace de travail générait également l'application principale et mon erreur était que j'avais par inadvertance inclus un nouveau fichier source (DLL) dans la liste des fichiers de construction de l'application elle-même .

Le programme principal nécessite le DLL en-tête mynewdll.h pour importer des choses mais ne nécessite pas le fichier source mynewdll.cpp. (Le code est introduit au moment de l'exécution avec une DLL.) J'ai un habitude d'inclure les fichiers d'en-tête et de code dans les projets en tant que paire, et c'est là que je me suis trompé.

J'aurais détecté l'erreur beaucoup plus tôt si j'avais été alerté et remarqué que le projet DLL lié sans erreur et c'était le programme principal qui se plaignait!

Mon DLL code source et projet était sans erreur et ce n'était que la façon dont j'ai essayé de construire mon exécutable qui était défectueux.

1
Ivan

Vérifiez que vous ne définissez pas les symboles exportés dans un autre projet. Nettoyez également tous les fichiers intermédiaires à la main et recompilez.

0
damian