สิ่งนี้ไม่ได้รวบรวม Python เข้ากับรหัสเครื่อง แต่อนุญาตให้สร้างไลบรารีที่ใช้ร่วมกันเพื่อเรียกรหัส Python
หากสิ่งที่คุณกำลังมองหาคือวิธีง่ายๆในการเรียกใช้โค้ด Python จาก C โดยไม่ต้องอาศัย execp คุณสามารถสร้างห้องสมุดสาธารณะจากรหัสหลามห่อด้วยโทรไม่กี่หลามฝัง API แอปพลิเคชันนี้เป็นไลบรารีที่ใช้ร่วมกันซึ่งเป็น. เพื่อให้คุณสามารถใช้ในไลบรารี / แอปพลิเคชันอื่น ๆ ได้
นี่คือตัวอย่างง่ายๆที่สร้างไลบรารีที่ใช้ร่วมกันซึ่งคุณสามารถเชื่อมโยงกับโปรแกรม C ได้ ไลบรารีที่ใช้ร่วมกันรันโค้ด Python
ไฟล์ python ที่จะเรียกใช้คือ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
คุณสามารถลองใช้กับpython2 -c "import pythoncalledfromc; pythoncalledfromc.main('HELLO')
. มันจะส่งออก:
python is called from c
string sent by «c» code is:
HELLO
end of «c» code input
ไลบรารีที่ใช้ร่วมกันจะถูกกำหนดโดยสิ่งต่อไปนี้callpython.h
:
#ifndef CALL_PYTHON
#define CALL_PYTHON
void callpython_init(void);
int callpython(char ** arguments);
void callpython_finalize(void);
#endif
ที่เกี่ยวข้องcallpython.c
คือ:
// 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();
}
คุณสามารถคอมไพล์ด้วยคำสั่งต่อไปนี้:
gcc `python2.7-config --ldflags` `python2.7-config --cflags` callpython.c -lpython2.7 -shared -fPIC -o callpython.so
สร้างไฟล์ชื่อcallpythonfromc.c
ที่มีสิ่งต่อไปนี้:
#include "callpython.h"
int main(void) {
char * example = "HELLO";
callpython_init();
callpython(&example);
callpython_finalize();
return 0;
}
รวบรวมและเรียกใช้:
gcc callpythonfromc.c callpython.so -o callpythonfromc
PYTHONPATH=`pwd` LD_LIBRARY_PATH=`pwd` ./callpythonfromc
นี่เป็นตัวอย่างพื้นฐานมาก มันสามารถใช้งานได้ แต่ขึ้นอยู่กับไลบรารีอาจยังยากที่จะทำให้โครงสร้างข้อมูล C เป็นอนุกรมกับ Python และจาก Python ถึง C สิ่งต่างๆอาจเป็นไปโดยอัตโนมัติได้บ้าง ...
Nuitkaอาจเป็นประโยชน์
นอกจากนี้ยังมีnumbaแต่ทั้งคู่ไม่ได้ตั้งใจที่จะทำในสิ่งที่คุณต้องการอย่างแน่นอน การสร้างส่วนหัว C จากโค้ด Python เป็นไปได้ แต่ถ้าคุณระบุวิธีการแปลงประเภท Python เป็นประเภท C หรือสามารถสรุปข้อมูลนั้นได้ ดูpython astroidสำหรับเครื่องวิเคราะห์ Python ast