Esto no compila Python al código de máquina. Pero permite crear una biblioteca compartida para llamar al código de Python.
Si lo que estás buscando es una manera fácil de ejecutar código Python desde C sin depender de cosas execp. Puede generar una biblioteca compartida desde el código de Python incluido con unas pocas llamadas al Python embedding API. Bueno, la aplicación es una biblioteca compartida, una .so que puede usar en muchas otras bibliotecas/aplicaciones.
Aquí hay un ejemplo simple que crea una biblioteca compartida, que puede vincular con un programa C. La biblioteca compartida ejecuta el código de Python.
El archivo pitón que se ejecutará es pythoncalledfromc.py
:
# -*- encoding:utf-8 -*-
# this file must be named "pythoncalledfrom.py"
def main(string): # args must a string
print "python is called from c"
print "string sent by «c» code is:"
print string
print "end of «c» code input"
return 0xc0c4 # return something
se puede probar con python2 -c "import pythoncalledfromc; pythoncalledfromc.main('HELLO')
. Es seria:
python is called from c
string sent by «c» code is:
HELLO
end of «c» code input
La biblioteca compartida se define mediante la siguiente por callpython.h
:
#ifndef CALL_PYTHON
#define CALL_PYTHON
void callpython_init(void);
int callpython(char ** arguments);
void callpython_finalize(void);
#endif
El asociada callpython.c
es:
// gcc `python2.7-config --ldflags` `python2.7-config --cflags` callpython.c -lpython2.7 -shared -fPIC -o callpython.so
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <python2.7/Python.h>
#include "callpython.h"
#define PYTHON_EXEC_STRING_LENGTH 52
#define PYTHON_EXEC_STRING "import pythoncalledfromc; pythoncalledfromc.main(\"%s\")"
void callpython_init(void) {
Py_Initialize();
}
int callpython(char ** arguments) {
int arguments_string_size = (int) strlen(*arguments);
char * python_script_to_execute = malloc(arguments_string_size + PYTHON_EXEC_STRING_LENGTH);
PyObject *__main__, *locals;
PyObject * result = NULL;
if (python_script_to_execute == NULL)
return -1;
__main__ = PyImport_AddModule("__main__");
if (__main__ == NULL)
return -1;
locals = PyModule_GetDict(__main__);
sprintf(python_script_to_execute, PYTHON_EXEC_STRING, *arguments);
result = PyRun_String(python_script_to_execute, Py_file_input, locals, locals);
if(result == NULL)
return -1;
return 0;
}
void callpython_finalize(void) {
Py_Finalize();
}
Se puede compilar con el siguiente comando :
gcc `python2.7-config --ldflags` `python2.7-config --cflags` callpython.c -lpython2.7 -shared -fPIC -o callpython.so
Crear un archivo llamado callpythonfromc.c
que contiene lo siguiente:
#include "callpython.h"
int main(void) {
char * example = "HELLO";
callpython_init();
callpython(&example);
callpython_finalize();
return 0;
}
compilarlo y ejecute:
gcc callpythonfromc.c callpython.so -o callpythonfromc
PYTHONPATH=`pwd` LD_LIBRARY_PATH=`pwd` ./callpythonfromc
Este es un ejemplo muy básico. Puede funcionar, pero dependiendo de la biblioteca puede ser difícil serializar las estructuras de datos C a Python y desde Python a C. Las cosas pueden automatizarse un poco ...
Nuitka puede ser útil.
También hay numba pero ambos no pretenden hacer exactamente lo que usted quiere. Es posible generar un encabezado C a partir del código Python, pero solo si especifica cómo convertir los tipos Python a tipos C o puede inferir esa información. Ver python astroid para un analizador Python ast.
Por cierto, su pregunta sería en mi humilde opinión más clara si usted pidió un "código de máquina" en lugar de código objeto. –
Gracias, he hecho ese cambio. –