ctypes에서 호출하는 c 함수에서 파이썬 개체를 인스턴스화 할 때 포함 된 파이썬 3.3 프로그램 segfaults.ctypes를 통해 호출 된 c 함수 내에서 파이썬 개체 인스턴스화
인터프리터를 설정 한 후, 나는 성공적 주요 C에서 파이썬 지능 (뿐만 아니라 사용자 정의 C 확장 유형)를 인스턴스화 할 수 있습니다 :
#import <Python/Python.h>
#define LOGPY(x) \
{ fprintf(stderr, "%s: ", #x); PyObject_Print((PyObject*)(x), stderr, 0); fputc('\n', stderr); }
// c function to be called from python script via ctypes.
void instantiate() {
PyObject* instance = PyObject_CallObject((PyObject*)&PyLong_Type, NULL);
LOGPY(instance);
}
int main(int argc, char* argv[]) {
Py_Initialize();
instantiate(); // works fine
// run a script that calls instantiate() via ctypes.
FILE* scriptFile = fopen("emb.py", "r");
if (!scriptFile) {
fprintf(stderr, "ERROR: cannot open script file\n");
return 1;
}
PyRun_SimpleFileEx(scriptFile, scriptPath, 1); // close on completion
return 0;
}
그때 PyRun_SimpleFileEx를 사용하여 파이썬 스크립트를 실행합니다. 잘 실행 표시하지만하는 ctypes, PyObject_CallObject 내부 프로그램 세그먼테이션 폴트 (segfault)를 통해 인스턴스화()를 호출 할 때 :
import ctypes as ct
dy = ct.CDLL('./emb')
dy.instantiate() # segfaults
lldb 출력 :
instance: 0
Process 52068 stopped
* thread #1: tid = 0x1c03, 0x000000010000d3f5 Python`PyObject_Call + 69, stop reason = EXC_BAD_ACCESS (code=1, address=0x18)
frame #0: 0x000000010000d3f5 Python`PyObject_Call + 69
Python`PyObject_Call + 69:
-> 0x10000d3f5: movl 24(%rax), %edx
0x10000d3f8: incl %edx
0x10000d3fa: movl %edx, 24(%rax)
0x10000d3fd: leaq 2069148(%rip), %rax ; _Py_CheckRecursionLimit
(lldb) bt
* thread #1: tid = 0x1c03, 0x000000010000d3f5 Python`PyObject_Call + 69, stop reason = EXC_BAD_ACCESS (code=1, address=0x18)
frame #0: 0x000000010000d3f5 Python`PyObject_Call + 69
frame #1: 0x00000001000d5197 Python`PyEval_CallObjectWithKeywords + 87
frame #2: 0x0000000201100d8e emb`instantiate + 30 at emb.c:9
왜 전화가 (인스턴스화 않습니다를)에서 실패 ctypes 만? 이 함수는 파이썬 lib를 호출 할 때만 충돌하기 때문에 아마도 일부 인터프리터 상태가 ctypes FFI 호출에 의해 방해 받고있을 것입니다.
dy_test()는 어떻게 인스턴스화됩니까? 인스턴스 메시지를 통해 온다면, 로그 메시지는 PyObject_CallObject가 완료되었음을 보여줍니다. 그렇지 않으면 LOGPY 출력을 볼 수 없습니다. 파이썬에서 PyLongObject 또는 다른 표준 호출 가능 함수를 사용할 수 있습니까? 그게 당신의 타입 설정에 문제가 있는지 말해 줄 것입니다. –
죄송합니다. 질문의 명확성을 위해 dy_test의 이름을 변경했습니다. 결정된. PyLong_Type을 전달하는 것과 같은 방식으로 실패합니다. 나는 그에 따라 복부를 줄일 것이다. – gwk
'CDLL'을'PyDLL'으로 바꾸면 더 잘 작동합니까? –