2012-01-17 6 views
0

ちょっとこれは疑問です。ユーザーが特定の属性を変更できるGUIを作成できるかどうかを尋ねられたので、GUIを使ってコードを変更することが可能かどうかを知りたいです。すなわちexmapleは、上記の GUIを使ってコードを変更する

start %= -(status) 
     > lexeme[elementV] 
     > -(lexeme[elementF]) 
     > +(inboundGroup); 

を下回っている例えばので Boost SPIRIT which parses Stringsである私のコードの一部であり、 * or -など

+ = One 
- = optional 
* = multiple 

+を変更することは可能であろうあなたはそれが可能だろうと思いますGUIを使ってそれを変更するにはどうすればいいのか分からないと思いますか?

すべてのヘルプ、私は非常に感謝されます

おかげShamari

+0

お使いのOSは? – Offirmo

答えて

1

すべてのプログラミング;-)実行中のプログラムの動的変更については

では可能であるが、そこにあるいくつかのソリューション:

  • LUAのような動的言語を使用する
  • ダイナミックなプラグインシステムを使用するローディング

あなたはC++とBoost Spiritが必要なので、最適な解決策は、その場でプラグインを生成してからロードすることです。

プログラムはコードを生成し、共有ライブラリ(.so)にコンパイルしてロードして実行します。 (。。。一部の人々はそれが汚れていますまた、安全でないです。しかし、それはシンプルだし、それが動作します)

ここでは、Linux用exempleです:plugin.h:我々必見

#ifndef PLUGIN_H__ 
#define PLUGIN_H__ 

#ifdef __cplusplus 
extern "C" { 
#endif 

int process(); 
typedef int (*plugin_process_fn_ptr)(); 

#ifdef __cplusplus 
} 
#endif 

#endif // PLUGIN_H__ 

extern Cを使用すると、C++の名前のマングリングによってシンボルをインポートするのが難しくなります。

plugin.cpp:私はここにハックを使用

#include "plugin.h" 
#include <iostream> 
using namespace std; 

int process() 
{ 
    int return_value = 0; 

#include "plugin_content.inc.cpp" 

    return return_value; 
} 

注意、コードが別のファイル、 "plugin_content.inc.cpp" から含まれます。ユーザーのコードが内部に配置されます。

プラグイン、 "build_plugin.sh" を構築するためのスクリプト:今

#! /bin/sh 

g++ -c -Wall -fPIC plugin.cpp -o plugin.o 
gcc -shared -o libplugin.so plugin.o 

呼び出しプログラム、メイン。

a.out 

とあなたが得る::

g++ -Wall -rdynamic -ldl main.cpp 

し、それを実行します。あなたのプログラムを構築し、

#include <iostream> 
#include <fstream> // to open files 
#include <dlfcn.h> // C lib to load dynamic libs 

#include "plugin.h" 

using namespace std; 

// load the plugin and call the process() function fom it 
static int process_via_plugin() 
{ 
    int return_value = -1; 

    void *lib_handle(NULL); 
    char *error(NULL); 

    char *plugin_lib = "./libplugin.so"; 
    lib_handle = dlopen(plugin_lib, RTLD_LAZY); 
    if (!lib_handle) 
    { 
     cerr << "Error loading lib " << plugin_lib << " : " << dlerror() << endl; 
     exit(1); 
    } 

    char *plugin_fn = "process"; 
    plugin_process_fn_ptr fn = (plugin_process_fn_ptr)dlsym(lib_handle, plugin_fn); 
    error = dlerror(); 
    if (error) 
    { 
     cerr << "Error finding lib " << plugin_fn << " : " << error << endl; 
     exit(1); 
    } 

    // call the function loaded from lib 
    return_value = (*fn)(); 

    dlclose(lib_handle); 
    lib_handle = NULL; // useless but for good habits ^^ 

    return return_value; 
} 

// build or rebuild the plugin, 
// we must call it when we change the plugin code code 
static int build_plugin(string code) 
{ 
    { 
     char *plugin_code_file = "plugin_content.inc.cpp"; 

     ofstream plugin_code(plugin_code_file, ios::out); 
     plugin_code << code << endl; 
    } 
    system("build_plugin.sh"); 

    return 0; 
} 

// our program 
int main(int argc, char *argv[]) 
{ 
    cout << "Hello World !" << endl; 

    string code = "" 
"cout << \"Hello from plugin !\" << endl;" 
""; 

    // build a first version of the plugin and call it 
    build_plugin(code); 
    process_via_plugin(); 

    // now we modify the code (use a GUI here) 
    code = "" 
"cout << \"Hello from plugin, updated !\" << endl;" 
""; 
    // rebuild the plugin and call it again 
    build_plugin(code); 
    process_via_plugin(); 

    // do it again as much as you want. 

    return 0; 
} 

をCPP

Hello World ! 
Hello from plugin ! 
Hello from plugin, updated ! 

私はあなたを与えるコード非常に基本的です。たとえば、プラグインのコンパイルが成功したかどうかをチェックし、エラーをユーザに報告する必要があります。今、あなたにはもっと多くのものを加えることがあなた次第です。

関連する問題