2010-01-16 6 views
1

J'ai commencé à étudier les DLL avec liaison implicite. Je ne comprends pas vraiment comment cela fonctionne. S'il vous plaît corrigez-moi où je me trompe. je ne ai pas compiler le code suivant (3 modules):DLL de liaison implicite question

malib.h

#ifdef MYLIBAPI 

#else 


#define MYLIBAPI extern "C" __declspec(dllimport) 

#endif 


MYLIBAPI int g_nResult; 

MYLIBAPI int Add(int nLeft, int nRight); 

Pour autant que je comprends est l'en-tête de la DLL. #define MYLIBAPI extern "C" __declspec(dllimport) signifie qu'ici nous allons déclarer certaines fonctions/variables qui seront décrites dans le fichier .cpp dédié et seront contenues dans une DLL.

MyLibFile1.cpp

#include <windows.h> 

#define MYLIBAPI extern "C" __declspec(dllexport) 

#include "MyLib.h" 

int g_nResult; 
int Add(int nLeft, int nRight) { 
    g_nResult = nLeft + nRight; 
    return(g_nResult); 
} 

Donc, cela est évidemment le fichier dans lequel sont mis en œuvre nos fonctions. C'est la partie de la DLL, n'est-ce pas?

MyExeFile1.cpp

#include <windows.h> 
#include <strsafe.h> 
#include <stdlib.h> 

#include "MyLib.h" 

int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) { 

    int nLeft = 10, nRight = 25; 

    TCHAR sz[100]; 
    StringCchPrintf(sz, _countof(sz), TEXT("%d + %d = %d"), 
     nLeft, nRight, Add(nLeft, nRight)); 
    MessageBox(NULL, sz, TEXT("Calculation"), MB_OK); 

    StringCchPrintf(sz, _countof(sz), 
     TEXT("The result from the last Add is: %d"), g_nResult); 
    MessageBox(NULL, sz, TEXT("Last Result"), MB_OK); 
    return(0); 
} 

Ainsi, c'est le fichier exécutable où nous utilisons les fonctions de la bibliothèque. Tout ne fonctionne pas. J'ai essayé de mettre tout cela dans un répertoire et de compiler à la fois. J'ai d'abord essayé de compiler une DLL à partir des deux premiers modules (avec succès), puis compiler l'exécutable (en changeant le chemin vers le fichier d'en-tête). Cependant, il a donné lieu à 2 erreurs deux fois:

erreur LNK2019: symbole externe non résolu _WinMain @ 16 référencé dans la fonction ___tmainCRTStartup

\ Visual Studio 2008 \ Projects \ MyExeFile1 \ Debug \ MyExeFile1.exe: LNK1120 erreur fatale: 1 les externals non résolus

Quelle est la bonne façon de faire cela - que dois-je changer dans le code et comment dois-je compiler le code (j'utilise VS2008)? Merci.

Répondre

1

#include <tchar.h> pour résoudre l'erreur de l'éditeur de liens.

Votre fichier d'en-tête doit ressembler à ceci:

#ifdef BUILDING_DLL 
# define MYLIBAPI extern "C" __declspec(dllexport) 
#else 
# define MYLIBAPI extern "C" __declspec(dllimport) 
#endif 

MYLIBAPI int __stdcall Add(int nLeft, int nRight); 

clic droit sur votre projet DLL dans l'Explorateur de solutions, Propriétés, C/C++, préprocesseur, Définitions préprocesseur, ajouter "BUILDING_DLL". Répétez pour la configuration Release.

Vous pouvez vérifier que votre DLL exporte correctement les fonctions avec Dumpbin.exe/exports.

Le déclarateur __declspec (dllimport) n'est pas strictement nécessaire, il le rend cependant plus efficace. L'attribut __stdcall n'est pas non plus nécessaire, il rend toutefois votre DLL utilisable à partir de n'importe quel langage prenant en charge l'exportation de DLL d'appel.

+0

Merci .. Je ne comprends pas vraiment ce qui se passe. Si j'ajoute une définition de préprocesseur, quand BUILDING_DLL est-il défini et quand? Quel est le but de cela? Je pense comme ceci: tandis que la DLL n'est pas compilée, le BUILDING_DLL n'est pas défini, donc nous importons les fonctions dans la DLL et après cela? ... (Je vois maintenant que je ne comprends pas du tout les parties de dllimport/dllexport) – lhj7362

+1

Il est # défini lorsque vous ajoutez la définition du préprocesseur. Vous l'avez fait dans le projet DLL, ce qui garantit que la fonction est exportée. Il n'est défini dans aucun autre projet, ce qui garantit que la fonction est importée. –

0

Modification de _tWinMain en WinMain dans MyExeFile1.cpp. Il cherche votre point d'entrée pour être nommé WinMain pas _tWinMain et ainsi l'éditeur de liens se plaint qu'il ne peut pas trouver WinMain.

Il existe des paramètres de projet qui déterminent le nom de la fonction de point d'entrée, mais je ne suis pas sûr lequel nécessiterait _tWinMain.

Modifier Selon cette annonce, _tWinMain est DEFINE que les cartes à winmain si vous incluez tchar.h. link text

+0

'_tWinMain' est susceptible d'être défini en fonction du paramètre' _UNICODE' de votre projet. – Dmitry

+0

Wow, vous avez raison. J'ai changé _tWinMain à WinMain et ai inclus tchar séparément, ainsi cela a fonctionné. Je ne comprends pas pourquoi il y avait une erreur «1 non résolue externe», ce qui m'inquiétait davantage. Mais de toute façon, merci! – lhj7362

0

Est-ce qu'il compile même? Ne devriez-vous pas #include <tchar.h> pour que tous les types et définitions de TCHAR fonctionnent?

+0

Il ne compile pas à cause d'une autre erreur. Il semble que l'inclusion de strsafe.h est suffisante. EDIT: probablement _tWinMain comprend tchar. – lhj7362

+0

'_tWinMain' est _defined_ dans tchar.h, il peut _not_ inclure tchar.h :) – Dmitry