2014-01-11 1 views
2

파이썬/C API로 몇 가지 테스트를하고 있는데, 어떻게 작동하고 어떻게 제대로 사용 하는지를 이해하고 있습니다. 내 목표는 C + + 코드에서 파이썬 스크립트를 실행할 수있는 C++ 래퍼를 만드는 것입니다. 외부 bindind 라이브러리 (예 : Boost.Python 또는 Cython)를 사용할 수 없습니다. 모든 것은 한 가지를 제외하고, 좋은 것입니다 : 릴리스 버전에서 PyImport_Import를 사용하는 지금, 나는로드 해요 스크립트를()Python 모듈 (PyObject *에서)을 이진 데이터로 변환하고 저장하여 나중에 사용하는 방법은 무엇입니까?

PyObject* py_module = PyImport_Import(py_module_name); //imports *.py file 
//do something, call functions, save results 
PyDecRef(py_module); 

그러나, 그들은 독점적 인 바이너리 형식으로 배포 및 시작시 메모리에로드해야합니다. 나는 이것을 달성하는 방법에 대한 힌트를 찾고있었습니다. 결과가 없습니다. 기본적으로 다음과 같이해야합니다.

File* file = fopen("scripts.bin", "rb"); 
char* c_buff = malloc(...); 
fread(c_buff, file, ...); 
PyObject* py_module = CreatePyObjectFromBinaryData(c_buff, ...); 

가능한 해결책을 제공해 줄 수 있습니까? 이 방법으로 마샬링 기능을 사용할 생각 :

FILE* file = fopen("scripts.bin", "wb"); 
PyMarshal_WriteObjectToFile(py_module, file, Py_MARSHAL_VERSION); 

그러나 이것은 작동하지 않는 것 같습니다. 사실, 문서에서 아무 것도 말하지 않기 때문에 어떤 방법으로 객체를 정렬 할 수 있는지 확신 할 수 없습니다.

옵션 질문 : 모든 * .py 파일이 내 바이너리 폴더에 있습니다. 시작시, PyImport_Import() 이후에/pycache에 바이트 코드 (.pyc)로 암시 적으로 컴파일됩니다. 컴파일 코드 모듈을 사용하여 바이트 코드 파일 ( .pyc 또는 * .pyo)을 만들 수 있다는 것을 알고 있습니다. 이 파일의 내용을 사용하여 모듈 데이터를 포함하는 PyObject를 생성 할 수 있습니까?

+0

파이썬 스크립트를 제공 할 수 있습니까? – Yakk

+0

내가 말한 초기 요구 사항 중 하나였습니다. 나는 '정찰'에 대한 책임이 있습니다 - 가능한 해결책과 그 복잡성은 무엇입니까? 이 문제에 대한 해결책이 성취하기 쉽지 않다면, 우리는 그것을 강요하지 않고 간단히 '원시'스크립트로 응용 프로그램을 선적하러 갈 것입니다. Py_CompileStringExFlags와 PyEval_EvalCodeEx가 훨씬 쉽습니다. 문제는 Py_CompileStringExFlags가 반환하는 코드 객체를 직렬화하고 응용 프로그램이 시작될 때마다 컴파일되는 원시 파일 대신 내용을 사용할 수 있습니까? –

+0

@Mateusz> ... 응용 프로그램이 시작될 때마다 컴파일됩니다. <- 그건 사실이 아닙니다. 만약 당신이 올바르게 이해하고 .pyc 파이썬 바이트 코드를 참조하고 있다면, 그것은 한 번 생성됩니다 - 그리고 당신은 심지어 파이썬 자체에서 오프라인 생성을 강제 할 수 있습니다.바이트 코드가 "쉽게"디 컴파일 될 수 있다는 점을 감안할 때, 왜 그렇게 붙어 있지 않은가? 간단한 배포 스크립트는 .py 파일을 복사/생성하고 시작 .pyc 생성을 강제 실행할 수 있습니다. – MariusSiuram

답변

0

.pyc 파일을 보내면됩니까? 이런 식으로 뭔가를 시도 :

의 pyc 파일에는 다음이 포함 :

int size; 
unsigned char *python_code; 
PyObject *mainobj; 
size = load_file("multiply.pyc", &python_code);  
Py_Initialize(); 
codeobj = PyMarshal_ReadObjectFromString(python_code+8, size-8); 
mainobj = PyImport_ExecCodeModule("multiply", codeobj); 
Py_Finalize(); 

것은이 토론을 ... 참조 Caersten Haese 말한다 https://groups.google.com/forum/#!topic/comp.lang.python/zhIe_Aa2Ih8

1) 마법을 포함하는 8 바이트 헤더 번호. 2) "marshal" 코드 객체의 직렬화.

코드 객체로 변환하려면 이 필요하며 8 바이트 헤더를 건너 뛰고 나머지는 비 정렬 화해야합니다.

.pyc 파일이 포함 된 암호화 된 zip 파일을 사용하는 데 실패 했습니까? (당신은 귀하의 C + + 코드에서 pwd를 인코딩해야합니다).

클라이언트를 신뢰할 수 없다면 진정으로 안전한 물건은 정말 어렵다고 생각합니다 (불가능합니까?).

관련 문제