Форум сайта python.su
Пытаюсь вызывать код питона из с++.
Во-первых в режиме debug не хотят импортироваться файлы завязанные на загрузку .pyd файлов, видимо это связано с тем, что .pyd файлы release?
во вторых странная ошибка с PIL Image
программа не хочет выполнять через PyRun_SimpleString строчку
if(!PyRun_SimpleString("img = Image.fromstring(\"L\", (size, size), img_str)")) LogMsg(_T("erorr\r\n"));
if(!PyRun_SimpleString("import Image"))
bool CPythonInterface::call_python_func_float(char* module,char* func_name,PyObject *pArgs, float& f) { PyObject *pName, *pModule, *pFunc; PyObject *pValue; //Py_Initialize(); pName = PyString_FromString(module); /* Error checking of pName left out */ pModule = PyImport_Import(pName); Py_DECREF(pName); if (pModule != NULL) { pFunc = PyObject_GetAttrString(pModule, func_name); /* pFunc is a new reference */ if (pFunc && PyCallable_Check(pFunc)) { pValue = PyObject_CallObject(pFunc, pArgs); Py_DECREF(pArgs); if (pValue != NULL) { bool is_float= PyFloat_Check(pValue); f= PyFloat_AsDouble(pValue); //PyArg_Parse(pValue, "f", f); //так падает //printf("Result of call: %ld\n", PyInt_AsLong(pValue)); Py_DECREF(pValue); } else { Py_DECREF(pFunc); Py_DECREF(pModule); PyErr_Print(); fprintf(stderr,"Call failed\n"); return false; } } else { if (PyErr_Occurred()) PyErr_Print(); fprintf(stderr, "Cannot find function \"%s\"\n", func_name); return false; } Py_XDECREF(pFunc); Py_DECREF(pModule); } else { PyErr_Print(); fprintf(stderr, "Failed to load \"%s\"\n", module); return false; } //Py_Finalize(); return true; }
Отредактировано mrgloom (Июнь 25, 2012 09:41:58)
Офлайн
да и еще вопрос проект в котором я вызываю функции из питона можно как то собрать с /MT , похоже работает только с /MD.
точнее с /MT вроде бы работает, но выдает ошибку
Отредактировано mrgloom (Июнь 25, 2012 10:44:48)
Офлайн
Про release/debug я вам уже ответил.
PyRun_SimpleString не работает, потому что не находит переменные size и img_str, полагаю.
Бинарные строки: вероятно, вам нужен http://docs.python.org/c-api/buffer.html#the-new-style-py-buffer-struct
Питон собран с /MD, поэтому компиляция его с /MT приводит к ошибкам runtime library. Решение только одно — пересобрать исходники питона и C Extensions с /MT
P.S. Очень порадовали вопросы, было приятно вернуться к давно забытым особенностям python embedding. Там есть еще одна штука: просто так вызывать питон из стороннего потока не выйдет, он крашится (пусть и не с первого раза). Если вам это нужно — расскажу, что делать.
И еще. Попробуйте boost.python — он сократит в разы объем взаимодействующего с питоном кода. Если, конечно, у вас нет жесткого ограничения на используемые библиотеки.
Офлайн
Андрей Светловнет, они там определены сверху в других PyRun_SimpleString, все таки какая то особенность с PIL Image.
PyRun_SimpleString не работает, потому что не находит переменные size и img_str, полагаю.
if(PyObject_CheckReadBuffer(pValue)) { const char* buf= new char[sz]; PyObject_AsCharBuffer(pValue, &buf, &sz); vector<unsigned char> vec; //вектор на выход чтобы не привязываться к памяти для питона unsigned char* p= (unsigned char*)buf; for(int i=0;i<sz;++i) { vec.push_back(*p); ++p; } delete[] buf;//тут всё падает }
const char* buf= PyMem_New(char, sz); ... PyMem_Del((void*)buf);//опять падает
int PyObject_AsCharBuffer(PyObject *obj, const char **buffer, Py_ssize_t *buffer_len)¶
Returns a pointer to a read-only memory location usable as character-based input. The obj argument must support the single-segment character buffer interface. On success, returns 0, sets buffer to the memory location and buffer_len to the buffer length. Returns -1 and sets a TypeError on error.
New in version 1.6.
Changed in version 2.5: This function used an int * type for buffer_len. This might require changes in your code for properly supporting 64-bit systems.
Returns a pointer to a read-only memory location usable as character-based input.может в этом дело?когда и как память нужно удалять?
This might require changes in your code for properly supporting 64-bit systems.и какие проблемы могут быть? надо ставить везде Int32?
Андрей Светловпопробую на досуге, сразу чего то у меня там не завелось.
Питон собран с /MD, поэтому компиляция его с /MT приводит к ошибкам runtime library. Решение только одно — пересобрать исходники питона и C Extensions с /MT
Отредактировано mrgloom (Июнь 27, 2012 14:35:28)
Офлайн
заработало, оказывается память сама выделяется и удаляется(правда непонятно как ибо деструктора то нету)
int sz=PyString_Size(pValue); const char* buf; PyObject_AsCharBuffer(pValue, &buf, &sz); vec.assign(buf,buf+sz);
Отредактировано mrgloom (Июнь 27, 2012 16:06:31)
Офлайн
Когда PyObject удаляется — убивается и его буфер.
Офлайн