40 votes

Appeler des fonctions dans une DLL à partir de C++

J'ai une solution dans VS 2008 avec 2 projets. L'un est une DLL écrite en C++ et l'autre est une simple application console C++ créée à partir d'un projet vierge. J'aimerais savoir comment appeler les fonctions de la DLL à partir de l'application.

Supposons que je commence avec un projet C++ vierge et que je veuille appeler une fonction appelée int IsolatedFunction(int someParam)

Comment l'appeler ?

21voto

jussij Points 7391

Il existe de nombreuses façons de procéder, mais je pense que l'une des options les plus simples consiste à lier l'application à la DLL au moment de la liaison, puis d'utiliser un fichier fichier de définition pour définir les symboles à exporter de la DLL.

CAVEAT : L'approche du fichier de définition fonctionne le mieux pour non décoré les noms des symboles. Si vous souhaitez exporter des symboles décorés, il est probablement préférable de NE PAS UTILISER l'approche du fichier de définition.

Voici un exemple simple de la manière de procéder.

Étape 1 : Définir la fonction dans le export.h fichier.

int WINAPI IsolatedFunction(const char *title, const char *test);

Étape 2 : Définir la fonction dans le export.cpp fichier.

#include <windows.h>

int WINAPI IsolatedFunction(const char *title, const char *test)
{
    MessageBox(0, title, test, MB_OK);
    return 1;
}

Étape 3 : Définir la fonction en tant qu'exportation dans le export.def fichier de définition.

EXPORTS    IsolatedFunction          @1

Étape 4 : Créez un projet DLL et ajoutez le fichier export.cpp y export.def à ce projet. La construction de ce projet créera un fichier export.dll et un export.lib fichier.

Les deux étapes suivantes établissent un lien avec la DLL au moment de la liaison. Si vous ne souhaitez pas définir les points d'entrée au moment de la liaison, ignorez les deux étapes suivantes et utilisez la commande Chargement de la bibliothèque y GetProcAddress pour charger le point d'entrée de la fonction au moment de l'exécution.

Étape 5 : Créer un Test pour utiliser la dll en ajoutant l'élément export.lib au projet. Copiez le fichier export.dll au même endroit que le fichier Test exécutable de la console.

Étape 6 : Appeler le Fonction isolée à partir de l'application Test, comme indiqué ci-dessous.

#include "stdafx.h"

// get the function prototype of the imported function
#include "../export/export.h"

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    // call the imported function found in the dll
    int result = IsolatedFunction("hello", "world");

    return 0;
}

0 votes

Au lieu d'ajouter les fichiers export.def à ce projet, j'ai besoin de pointer vers le fichier .def dans Linker -> Input -> Module Definition File comme $(SolutionDir)export.def

1 votes

Vous avez besoin de #include <Windows.h> pour l'étape 6 également.

1 votes

Vous avez raison de dire que la Windows.h est nécessaire. Dans l'exemple ci-dessus, j'ai utilisé la fonction #include "stdafx.h" qui est le fichier d'en-tête précompilé. Dans le cas présent, ce fichier contenait le fichier Windows.h inclure.

9voto

Ismael Points 2339

On peut aussi exporter des fonctions de la dll et les importer de l'exe, c'est plus délicat au début mais c'est finalement beaucoup plus facile que d'appeler LoadLibrary/GetProcAddress. Voir MSDN .

Lors de la création du projet avec l'assistant VS, il y a une case à cocher dans la dll qui vous permet d'exporter des fonctions.

Ensuite, dans l'application exe, il suffit d'inclure un en-tête de la dll avec les définitions appropriées et d'ajouter le projet de dll comme dépendance à l'application exe.

Consultez cette autre question si vous souhaitez approfondir ce point. Exporter des fonctions d'une DLL avec dllexport .

6voto

Franci Penov Points 45358

Vous pouvez soit utiliser la méthode LoadLibrary/GetProcAddress (comme Harper l'a mentionné dans sa réponse, voici le lien vers la page d'accueil de LoadLibrary/GetProcAddress), soit utiliser la méthode LoadLibrary/GetProcAddress. liaison dynamique au moment de l'exécution échantillon MSDN ) ou vous pouvez lier votre application console au fichier .lib produit à partir du projet DLL et inclure le fichier hea.h avec la déclaration de votre fonction (comme décrit dans la section load-time dynamic linking MSDN sample )

Dans les deux cas, vous devez vous assurer que votre DLL exporte correctement la fonction que vous souhaitez appeler. La façon la plus simple de le faire est d'utiliser __declspec(dllexport) dans la déclaration de la fonction (comme indiqué dans l'exemple de création d'une DLL). bibliothèque de liens dynamiques simple échantillon MSDN ), bien que vous puissiez également le faire par l'intermédiaire du fichier .def correspondant dans votre projet DLL.

Pour plus d'informations sur les DLL, nous vous invitons à consulter la rubrique MSDN À propos des bibliothèques de liens dynamiques sujet.

6voto

Les cinq étapes suivantes sont nécessaires :

  1. déclarer le pointeur de fonction
  2. Charger la bibliothèque
  3. Obtenir l'adresse de la procédure
  4. l'assigner au pointeur de fonction
  5. appeler la fonction à l'aide d'un pointeur de fonction

Vous trouverez la capture d'écran de l'IDE VC++ étape par étape à l'adresse suivante http://www.softwareandfinance.com/Visual_CPP/DLLDynamicBinding.html

Voici l'extrait de code :

int main()
{
/***
__declspec(dllimport) bool GetWelcomeMessage(char *buf, int len); // used for static binding
 ***/
    typedef bool (*GW)(char *buf, int len);

    HMODULE hModule = LoadLibrary(TEXT("TestServer.DLL"));
    GW GetWelcomeMessage = (GW) GetProcAddress(hModule, "GetWelcomeMessage");

    char buf[128];
    if(GetWelcomeMessage(buf, 128) == true)
        std::cout << buf;
        return 0;
}

1voto

ssg Points 20321

Afin d'éviter le chargement au moment de l'exécution, vous devez établir un lien avec le fichier .LIB fourni par la DLL et utiliser des fichiers .H pour les déclarations de fonctions. Cela entraînera la création d'une table d'importation dans votre exécutable, ce qui permettra au chargeur d'images Windows de lier les fonctions DLL dans votre code au démarrage, vous épargnant ainsi l'effort de LoadLibrary/GetProcAddress.

Si vous ne disposez pas des fichiers d'en-tête, vous pouvez les réécrire en utilisant la directive __declspec(dllimport), si vous savez comment ils sont déclarés.

Si vous ne disposez pas du fichier .LIB, vous devrez peut-être recourir à la méthode LoadLibrary/GetProcAddress mentionnée ci-dessus.

http://en.wikipedia.org/wiki/Dynamic-link_library#C_and_C.2B.2B_2

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X