#include <string>
#include <cstring>
#include <cassert>
#include <regex>
#include <unistd.h>
#include <dlfcn.h>
void *build_and_dlopen(const std::string &code)
{
//fprintf(stderr,">>%s<<\n",code.c_str());
char filename[128];
snprintf(filename,128,"/tmp/edgeXXXXXX.cpp");
auto dot = strrchr(filename,'.');
assert(dot);
auto fd= mkstemps(filename, (&filename[strlen(filename)])-dot /*suffixlen*/);
write(fd,code.c_str(),code.length());
//fprintf(stderr,"filename: %s\n", filename);
std::string object_filename = filename;
object_filename = std::regex_replace(object_filename,std::regex("cpp$"),"so");
//fprintf(stderr,"object_filename: %s\n", object_filename.c_str());
// examples:
// clang++-9 -fPIC -shared -o /tmp/edgehELGdQ.so /tmp/edgehELGdQ.cpp
// nm -gD /tmp/edgehELGdQ.so # show C-lang syms
char cmd[384];
snprintf(cmd,384,"clang++-9 -std=c++2a -O3 -fPIC -shared -o %s %s 2>&1", object_filename.c_str(), filename);
auto p = popen(cmd,"r");
std::array<char, 1024> buffer;
std::string result;
while(!feof(p))
if (fgets(buffer.data(), 1024, p) != nullptr)
result += buffer.data();
auto rc=pclose(p);
if(rc)
fprintf(stderr,"%s\n", result.c_str());
assert(0==rc);
close(fd);
unlink(filename);
// link filter into program
auto handle=dlmopen(LM_ID_NEWLM,object_filename.c_str(), RTLD_NOW); // leak
unlink(object_filename.c_str());
assert(handle);
return handle;
}
int main() {
std::string code = R"(
#include <iostream>
extern "C" {
void make_me_a_better_program()
{
std::cout << "stuffez" << std::endl;
}
}
)";
auto handle = build_and_dlopen(code);
auto sym_handle=dlsym(handle,"make_me_a_better_program");
assert(sym_handle);
auto make_me_a_better_program = (void (*)())sym_handle;
make_me_a_better_program();
return 0;
}
To embed this project on your website, copy the following code and paste it into your website's HTML: