2009-02-03 8 views
10

Sooooo J'écris un interpréteur de script. Et au fond, je veux des classes et fonctions stockées dans une DLL, mais je veux la DLL de chercher des fonctions au sein des programmes qui sont un lien vers elle, comme,Compiler une DLL avec gcc

 program    dll 
---------------------------------------------------- 
send code to dll-----> parse code 
           | 
           v 
          code contains a function, 
          that isn't contained in the DLL 
           | 
list of functions in <------/ 
program 
     | 
     v 
corresponding function, 
user-defined in the 
program--process the 
passed argument here 
     | 
     \--------------> return value sent back 
          to the parsing function 

je me demandais essentiellement, comment puis-je compiler une DLL avec gcc? Eh bien, j'utilise un port windows de gcc. Une fois que j'ai compilé un .dll contenant mes classes et fonctions, comment puis-je lier avec mon programme? Comment utiliser les classes et les fonctions dans la DLL? Est-ce que la DLL peut appeler des fonctions du programme qui s'y connecte? Si je fais un objet {...} de classe; dans la DLL, puis lorsque la DLL est chargée par le programme, objet sera disponible pour le programme? Merci d'avance, j'ai vraiment besoin de savoir comment travailler avec les DLL en C++ avant de pouvoir continuer avec ce projet.

"Pouvez-vous ajouter plus de détails sur les raisons pour lesquelles vous souhaitez que la DLL appelle des fonctions dans le programme principal?" Je pensais que le diagramme l'expliquait en quelque sorte ... le programme utilisant la DLL passe un morceau de code à la DLL, qui analyse le code, et si des appels de fonction sont trouvés dans le code, alors les fonctions correspondantes dans la DLL sont appelé ... par exemple, si j'ai passé "a = sqrt (100)" alors la fonction d'analyseur de DLL trouverait l'appel de fonction à sqrt(), et dans la DLL serait une fonction sqrt() correspondante qui calculerait le carré La racine de l'argument lui est transmise, puis elle prend la valeur de retour de cette fonction et la place dans la variable a ... comme n'importe quel autre programme, mais si un gestionnaire correspondant pour la fonction sqrt() n'est pas trouvé dans la DLL (il y aurait une liste de fonctions supportées nativement) alors il appellerait une fonction similaire qui résiderait dans le programme en utilisant la DLL pour voir s'il y a des fonctions définies par l'utilisateur par ce nom. Donc, disons que vous avez chargé la DLL dans le programme donnant à votre programme la possibilité d'interpréter les scripts de ce langage particulier, le programme pourrait appeler les DLL pour traiter des lignes de code simples ou remettre les noms de fichiers de scripts à traiter ... mais si vous voulez ajouter une commande dans le script qui convient à votre programme, vous pouvez définir une valeur booléenne dans la DLL en lui disant que vous ajoutez des fonctions à son langage et ensuite créer une fonction dans votre code qui listerait les fonctions que vous ajoutez (la DLL l'appellera avec le nom de la fonction qu'elle veut, si cette fonction est une fonction définie par l'utilisateur contenue dans votre code, la fonction appellera la fonction correspondante avec l'argument qui lui est passé par la DLL , retourne la valeur de retour de la fonction définie par l'utilisateur à la DLL, et si elle n'existait pas, elle retournerait un code d'erreur ou NULL ou s quelque chose). Je commence à voir que je vais devoir trouver un autre moyen de contourner cela pour faire les appels de fonction vont dans un seul sens

+0

wow, je ne savais même pas qu'il y avait un port gagnant de gcc. J'aurais essayé d'utiliser gcc avec les fenêtres comme cible de la plateforme. – cbrulak

+0

Vous devriez probablement spécifier le compilateur exact que vous utilisez. Probablement la documentation pour ce compilateur vous indique comment faire des DLL. – SoapBox

+0

ça s'appelle mingw, ou mingw32 je suppose ... j'essaierai de trouver la documentation de gcc mais je suis assez nouveau en C et en C++ donc certains aspects sont difficiles à comprendre encore – user61721

Répondre

-1

Vous pouvez toujours charger le dll lors de l'exécution avec load library

+0

Ok, merci , J'ai toujours du mal à comprendre comment le compiler, et comment obtenir la DLL pour rechercher des procédures dans le programme qui l'appelle, si c'est possible – user61721

8

This link explique comment le faire d'une manière basique.

Dans une grande vue d'image, lorsque vous créez une DLL, vous créez une bibliothèque qui est chargée à l'exécution. Il contient un certain nombre de symboles qui sont exportés. Ces symboles sont généralement des références à des méthodes ou des fonctions, plus compilateur/éditeur de liens.

Lorsque vous créez normalement une bibliothèque statique, il y a un minimum de goo et l'éditeur de liens extrait le code dont il a besoin et le reconditionne pour vous dans votre exécutable.

Dans une DLL, vous obtenez en fait deux produits finaux (trois vraiment attendre): une DLL et une bibliothèque de bout. Le stub est une bibliothèque statique qui ressemble exactement à votre bibliothèque statique régulière, sauf qu'au lieu d'exécuter votre code, chaque stub est généralement une instruction de saut vers une routine commune.La routine courante charge votre DLL, obtient l'adresse de la routine que vous souhaitez appeler, puis corrige l'instruction de saut d'origine pour y aller, donc quand vous l'appelez à nouveau, vous vous retrouvez dans votre DLL.

Le troisième produit final est généralement un fichier d'en-tête qui vous dit tout sur les types de données dans votre bibliothèque. Par conséquent, vos étapes sont les suivantes: créez vos en-têtes et codez, créez une DLL, créez une bibliothèque de raccord à partir des en-têtes/code/une liste de fonctions exportées. Le code de fin sera lié à la bibliothèque de bout qui chargera la DLL et réparera la table de saut.

compilateur/goo éditeur de liens inclut des choses comme en vérifiant que les bibliothèques d'exécution sont là où ils sont nécessaires, en vous assurant que les constructeurs statiques sont exécutés, en vous assurant que Destructeurs statiques sont enregistrés pour une exécution ultérieure, etc, etc, etc.

Maintenant, en ce qui concerne votre problème principal: comment écrire du code extensible dans une DLL? Il y a un certain nombre de manières possibles - une manière typique est de définir une classe abstraite pure (aka l'interface) qui définit un comportement et le passe dans une routine de traitement ou crée une routine pour enregistrer des interfaces pour faire le travail, routine demande au bureau d'enregistrement un objet pour gérer une pièce de travail pour cela.

+0

c'est un peu sur ma tête .. "Normalement, vous ' d créer cette liste à la main avec un éditeur de texte, "comment créer le fichier d'export? Qu'est-ce qu'une DLL cygwin?Puis-je mettre des classes dans une DLL? – user61721

2

Sur le détail de ce que vous envisagez de résoudre, peut-être vous devriez regarder un analyseur extensible comme lua au lieu de construire le vôtre.

À votre attention plus spécifique.
Une DLL est (généralement?) Destinée à être complète en elle-même, ou explicitement savoir quelles autres bibliothèques utiliser pour se compléter. Ce que je veux dire par là, vous ne pouvez pas avoir une méthode implicitement fournie par l'application appelante pour compléter la fonctionnalité de DLL.

Vous pouvez toutefois intégrer une partie de votre API à la fourniture de méthodes à partir d'une application appelante, ce qui rend la DLL entièrement contenue et le transfert de connaissances explicite.

Comment utiliser les classes et les fonctions dans la DLL?
Inclure les en-têtes dans votre code, lorsque le module (exe ou un autre dll) est lié les dll sont vérifiés pour l'exhaustivité.

L'appel DLL peut-il fonctionner à partir du programme qui le lie?
Oui, mais il faut en parler à l'exécution.

Si je crée un objet de classe {...}; dans la DLL, puis lorsque la DLL est chargée par le programme, objet sera disponible pour le programme?
Oui, il sera disponible, mais il y a certaines restrictions dont vous devez être conscient. Tels que dans le domaine de la gestion de la mémoire, il est important soit:

  • Lien tous les modules partagent la mémoire avec le même dll de gestion de la mémoire (généralement c runtime)
  • Assurez-vous que la mémoire est allouée et dealloccated seulement dans le même module.
  • allouent sur la pile

Exemples!
Voici une idée de base de passer des fonctions à la DLL, mais dans votre cas, peut-être pas le plus utile que vous avez besoin de savoir à l'avance quelles autres fonctions que vous voulez fournir. bit

// parser.h 
struct functions { 
    void *fred (int); 
}; 

parse(string, functions); 

// program.cpp 
parse("a = sqrt(); fred(a);", functions); 

Qu'est-ce que vous avez besoin est une façon d'enregistrer les fonctions (et leurs coordonnées avec le dll.) Le plus grand problème est les détails ici. Mais ignorer que vous pourriez faire quelque chose comme wxWidgets fait avec l'inscription de classe. Quand method_fred est compilé par votre application, il appelle le constructeur et s'enregistre avec la DLL via l'utilisation de methodInfo. Parser peut rechercher methodInfo pour les méthodes disponibles.

// parser.h 
class method_base { }; 
class methodInfo { 
    static void register(factory); 
    static map<string,factory> m_methods; 
} 

// program.cpp 
class method_fred : public method_base { 
    static method* factory(string args); 
    static methodInfo _methoinfo; 
} 
methodInfo method_fred::_methoinfo("fred",method_fred::factory); 
0

Cela ressemble à un travail pour les structures de données.

Créez une structure contenant vos mots-clés et la fonction associée à chacun d'eux.

struct keyword { 
    const char *keyword; 
    int (*f)(int arg); 
}; 

struct keyword keywords[max_keywords] = { 
    "db_connect", &db_connect, 
} 

écrire alors une fonction dans votre DLL que vous passez l'adresse de ce tableau à:

plugin_register(keywords); 

Ensuite, dans la DLL qu'il peut faire:

keywords[0].f = &plugin_db_connect; 

Avec cette méthode, le code pour gérer les mots-clés de script reste dans le programme principal tandis que la DLL manipule les structures de données pour obtenir ses propres fonctions appelées. En le prenant en C++, faites à la place une struct qui contient un std :: vector ou std :: map ou n'importe quel mot-clé et quelques fonctions pour les manipuler.

0

Winrawr, avant de continuer, lire ce qui suit:

Any improvements on the GCC/Windows DLLs/C++ STL front?

Fondamentalement, vous pouvez rencontrer des problèmes lors du passage des chaînes de STL autour de vos DLL, et vous pouvez aussi avoir des problèmes avec exceptions qui survolent les limites de la DLL, bien que ce ne soit pas quelque chose que j'ai déjà expérimenté.

Questions connexes