すべてのプログラミング;-)実行中のプログラムの動的変更については
では可能であるが、そこにあるいくつかのソリューション:
- 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 !
私はあなたを与えるコード非常に基本的です。たとえば、プラグインのコンパイルが成功したかどうかをチェックし、エラーをユーザに報告する必要があります。今、あなたにはもっと多くのものを加えることがあなた次第です。
お使いのOSは? – Offirmo