-
Notifications
You must be signed in to change notification settings - Fork 2
Worker
The Worker class is a class that allows to compile and execute code in c++ inside the platform.
This class is used to allow code generation at the moment and insert it at run time.
A new worker is defined as:
Worker<T, T1>(std::string header, std::string footer, std::string functionName,
std::string commandLine, std::string path, bool deleteFiles = true)
were each parameter is:
- T : The type of the return value
- T1 : The types of the parameter values of the call.
-
header : The header to attach to the code (it must contain an extern "C"), for example
"#include <vector> #include <exception> #include <stdexcept> #include <string> #include <algorithm> #include <iostream> #include <cstdlib> #include <ctime> #include \"Bundle/BundleInfo.h\" #include \"adtnPlus/Json.h\" #include \"adtnPlus/Worker.h\" extern \"C\" { const uint64_t g_timeFrom2000 = 946684800; using json = nlohmann::json; bool f(Json& ns, Json& bs, json bp) {"
-
footer : The footer to attach to the code (it must close the extern C and the function), for example
"return true;}}"
- functionName: The name of the function that will be loaded from the generated library, in this example f
-
commandLine : The command line used to generate the shared library (it will contain two %s, the first for the code file and the second for the library output name), for example
"g++ -w -fPIC -shared -std=c++14 %s -Wl,--no-whole-archive -o %s -lpthread 2>&1"
- path : The path to save the generated library and the auxiliary .cpp files.
- deleteFiles : If set to true if will deleted all the generated files.
After define a worker you must call the
void generateFunction(std::string code);
This call will generate the cpp and so file with all the given parameters, and attaching between the header and the footer the given code. It throws a WorkerException if for some reason the library has not been created.
When the code is already generated it can be executed with
void execute(Args &.. params);
This function takes the same arguments defined in T1, for example
worker.execute(m_nodeState, bundleState, bundleProcessState);
This function executes the function asynchronous, so to retrieve the result you must call the
T getResult();
This returns the result of the execute call, returning the value of the type defined at T. If the function can not return a result a WorkerException is thrown.
std::string header = "extern \"C\" {int r(int& value) {"; // the header containing the signature of the function
std::string footer = "}}"; // the footer with the closing brackets
std::string commandLine = "g++ -w -fPIC -shared %s -o %s 2>&1"; // the compiling line
std::string code = "return value * 10;"; // the code to generate
int val = 10;
Worker<int, int> w(header, footer, "r", commandLine, "./"); // the worker definition
w.generateFunction(code);
w.execute(val);
w.getResult(); // return 100
This example generates a simple function that takes an int
as input parameters and returns an int
.
The functions is as simple as returning the input value multiplied by 10.
std::string header = "#include <string>\n"
"#include <vector>\n"
"#include <sstream>\n"
"extern \"C\" {std::string r(std::vector<std::string> values) {";
std::string footer = "}}";
std::string commandLine = "g++ -w -fPIC -shared %s -o %s 2>&1";
std::string code = "std::stringstream ss;"
"for (int i = 0; i < values.size(); ++i) {"
" ss << values[i].at(0);}"
"return ss.str();";
Worker<std::string, std::vector<std::string>> w(header, footer, "r",
commandLine, "./");
w.generateFunction(code);
std::vector<std::string> params;
params.push_back("This");
params.push_back("Is");
params.push_back("A");
params.push_back("Test");
w.execute(params);
w.getResult(); // returns "TIAT"
This time a string
and a vector<string>
are used as input and return values.
std::string header = "#include <string>\n"
"#include <vector>\n"
"extern \"C\" {int r(int& value, std::string val2, "
"std::vector<std::string> value3) {";
std::string footer = "}}";
std::string commandLine = "g++ -w -fPIC -shared -std=c++11 %s -o %s 2>&1";
std::string code = "int res = value;"
"for (std::string s : value3) {"
" res += std::stoi(s);"
"}"
"res += std::stoi(val2);"
"return res;";
Worker<int, int, std::string, std::vector<std::string>> w(header, footer, "r",
commandLine, "./");
int value = 10;
std::string val2 = "20";
std::vector<std::string> params;
params.push_back("10");
params.push_back("20");
params.push_back("30");
params.push_back("40");
w.generateFunction(code);
w.execute(value, val2, params);
w.getResult(); // return 130;
This example shows the use of multiple parameters of different types.