2010-03-28 3 views
1

Je me demande si quelqu'un sait comment effectuer ce qui suit:Accès C++ Fonctions de la mémoire du texte

Disons que j'ai un tas de données stockées dans SQL, permet de dire que l'un des champs qu'on pourrait appeler funcName, fonction Le nom contiendrait des données similaires à "myFunction" Ce que je me demande, est-ce qu'il y a un moyen que je peux à son tour d'extraire le nom de la fonction et d'appeler réellement cette fonction?

Il y a plusieurs façons de penser à cela, on change funcName en funcId et on se connecte à un tableau ou similaire, mais je cherche quelque chose d'un peu plus dynamique qui me permettrait d'ajouter les données sur fly sans avoir à mettre à jour le code source réel chaque fois que j'ajoute un appel à une nouvelle fonction en supposant bien sûr que la fonction existe déjà et est accessible via l'emplacement de l'étendue à partir de laquelle nous l'appelons.

Toute aide serait grandement appréciée.

Répondre

3

Utilisez une macro pour définir de nouvelles fonctions qui s'enregistrent automatiquement.

// callable_function.h 
class CallableFunction { 
public: 
    virtual void operator()() = 0; 
}; 

class CallableFunctionRegistry { 
public: 
    static CallableFunction *Register(const string &func_name, 
            CallableFunction *func_impl) { 
    Instance()->registered_functions_.insert(make_pair(func_name, func_impl)); 
    } 

    static void Run(const string &func_name) { 
    (*Instance()->registered_functions_[func_name])(); 
    } 

private: 
    static CallableFunctionRegistry *Instance() { 
    static CallableFunctionRegistry *instance = new CallablefunctionRegistry; 
    return instance; 
    } 

    CallableFunctionRegistry() {} 
    map<string, CallableFunction*> registered_functions_; 
}; 

#define REGISTER_CALLABLE_FUNCTION(FuncName) \ 
    class FuncName : public CallableFunction { \ 
    public: \ 
    virtual void operator()(); \ 
    }; \ 
    CallableFunction *impl_ ##FuncName = \ 
    CallableFunctionRegistry::Register(#FuncName, new FuncName); \ 
    void FuncName::operator()() 

Et l'utiliser comme ceci:

//other_file.cc 
REGISTER_CALLABLE_FUNCTION(DoStuff) { 
    // do stuff here. 
} 

Et ceci:

//yet_another_file.cc 
CallableFunctionRegistry::Run("DoStuff"); 

Vous pouvez le faire avec la fonction PTR au lieu d'objet CallableFunction, mais ma syntaxe c'est floue. De toute façon, ajoutez une vérification d'erreur pour les enregistrements en double et la recherche n'est pas trouvée.

+0

Wow, même si je n'utilise peut-être pas ce code, cela m'a conduit à une autre voie que je vais essayer un peu plus tard pour atteindre mon objectif. Merci beaucoup pour la réponse et l'information =). – Undawned

+0

Bonne chance, content de pouvoir aider. – Stephen

1

Vous pouvez utiliser le texte que vous recevied de SQL et appelez GetProcAddress()

cela vous donnera un pointeur de fonction, vous pouvez appeler (en supposant que vous utilisez Windows).

Pour Linux, jetez un oeil à dlsym

+0

Corrigez-moi si je me trompe, mais il semble que GetProcAddress() fait référence aux fonctions/variables exportées dans les DLL, mon programme actuel n'exporte rien dans DLL. – Undawned

+0

@Undawned Ensuite, vous devrez créer une DLL qui exporte toutes les fonctions que vous voulez utiliser. – SigTerm

+0

Vous pouvez également exporter des fonctions à partir d'un fichier .EXE sans avoir besoin de DLL. –

2

Installation d'un mappage des noms des pointeurs de fonction ou foncteurs au démarrage du programme, puis appeler par son nom par carte recherche. Peut également utiliser des bibliothèques dynamiques pour les extensions. Dans le monde du compilateur/interpréteur, il s'agit d'un symbol table, qui contient également généralement le type (classes/structures), les déclarations de données (variables) et les descripteurs de fonction (arguments et types de retour, etc.). Il peut également être imbriqué à la portée.

1

Approche # 1 (le plus compliqué):
plugin développement d'un système composé de plusieurs bibliothèques liées dynamiquement (* .dll sur la victoire, * .so sur Linux), avec quelques fonctions publiques qui raconteront votre application qui ce plugin supports, noms de fonctions et pointeurs. Rechercher les plugins au démarrage, construire la liste des fonctions qui mapperont les noms des fonctions à leurs pointeurs.

Attendez-vous à des problèmes avec un nombre variable de paramètres. Approche # 2 (force brute): Stockez toutes les fonctions que vous devriez pouvoir appeler dans une bibliothèque liée dynamiquement. Lorsque le nom de la fonction est extrait de la base de données, obtenez le pointeur de fonction en utilisant GetProcAddress (win32) ou dlsym (?) Sous linux.

Attendez-vous à des problèmes avec un nombre variable de paramètres. Pas le plus rapide, et pas le plus intelligent.

Approche n ° 3 (la plus flexible): Intégrez l'interpréteur lua ou python dans votre application.
De cette façon, vous pourrez stocker des fonctions entières dans la base de données et ne devriez pas avoir de problèmes pour appeler l'une de ces fonctions. Vous devrez toujours déclarer la liste des fonctions auxquelles vous souhaitez accéder. Ce ne sera pas un fou/hack proof, cependant, il sera possible de bousiller toute l'application à partir de la base de données, si vous n'êtes pas assez prudent.

+0

Bonne réponse, malheureusement les méthodes suggérées nécessitent un peu trop de révision sur l'ensemble du projet lui-même alors que ce sur quoi je travaille est une plus petite partie du projet qui ne justifie pas une révision aussi importante du code de base. Merci pour l'information si =). – Undawned

Questions connexes