通过GUI修改代码

时间:2012-01-17 09:56:14

标签: c++ user-interface boost-spirit

嘿,这更像是一个问题,我想知道是否有可能通过GUI询问修改代码,因为我被要求查看是否可以创建用户可以更改某些属性的GUI。即一个例子在下面

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

以上是我的代码Boost SPIRIT which parses Strings的一部分,例如,可以将+更改为* or -

+ = One 
- = optional
* = multiple

你认为通过GUI改变它是否可能我认为它可能只是不确定如何做到这一点?

任何帮助我将非常感激

感谢Shamari

1 个答案:

答案 0 :(得分:1)

编程中一切皆有可能; - )

为了在执行期间动态修改程序,有几种解决方案:

  • 使用LUA等动态语言
  • 使用动态加载的插件系统

由于您需要C ++和Boost Spirit,我认为最好的解决方案是动态生成插件并在之后加载它。

您的程序将生成代码,将其编译为共享库(。so),然后加载并执行它。 (有些人会发现它很脏。它也不安全。但它很简单而且有效。)

以下是linux的例子: 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;
}

请注意,我在这里使用hack,代码将包含在另一个文件“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

现在调用程序 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;
}

现在,建立您的计划:

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

并执行它:

a.out

你得到:

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

我给你的代码非常基本。例如,我们应该检查插件的编译是否成功并向用户报告错误。现在由您来添加更多内容。