Hello,
I wanted to know if you have a idea about how I could import Python bindings in C++ to do something like
import compile, marshal
xyz = compile(code)
marshal.dump(xyz)
then get the result so I could write it to a new file.
I got the marshal output apparently with:
Code
{
PyObject* code = Py_CompileStringExFlags(text, filename, Py_file_input, NULL, 0);
PyObject* marshalled = PyMarshal_WriteObjectToString(code, Py_MARSHAL_VERSION);
Py_CLEAR(code);
if (marshalled == NULL) {
return NULL;
}
assert(PyBytes_CheckExact(marshalled));
return marshalled;
}
static char* get_varname(const char* name, const char* prefix)
{
size_t n = strlen(prefix);
char* varname = (char*)malloc(strlen(name) + n + 1);
(void)strcpy(varname, prefix);
for (size_t i = 0; name[i] != '\0'; i++) {
if (name[i] == '.') {
varname[n++] = '_';
}
else {
varname[n++] = name[i];
}
}
varname[n] = '\0';
return varname;
}
static void write_code(FILE* outfile, PyObject* marshalled, const char* varname)
{
unsigned char* data = (unsigned char*)PyBytes_AS_STRING(marshalled);
size_t data_size = PyBytes_GET_SIZE(marshalled);
fprintf(outfile, "const unsigned char %s[] = {\n", varname);
for (size_t n = 0; n < data_size; n += 16) {
size_t i, end = Py_MIN(n + 16, data_size);
fprintf(outfile, " ");
for (i = n; i < end; i++) {
fprintf(outfile, "%u,", (unsigned int)data[i]);
}
fprintf(outfile, "\n");
}
fprintf(outfile, "};\n");
}
static int write_frozen(const char* outpath, const char* inpath, const char* name,
PyObject* marshalled)
{
FILE* outfile = fopen(outpath, "w");
if (outfile == NULL) {
fprintf(stderr, "cannot open '%s' for writing\n", outpath);
return -1;
}
fprintf(outfile, "%s\n", "/*HellWorld*/");
char* arrayname = get_varname(name, "_Py_M__");
write_code(outfile, marshalled, arrayname);
free(arrayname);
if (ferror(outfile)) {
fprintf(stderr, "error when writing to '%s'\n", outpath);
return -1;
}
fclose(outfile);
return 0;
}
And in my main function:
PyObject* marshalled = compile_and_marshal(templateOutput.c_str(), "test.txt");
write_frozen("marshaled.txt", "marshaled.txt", "marshaled", marshalled);
But I still miss how to convert it to integrate it to a python script using marshall.loads(<arg>)
Regards.