boost.python как передать и получить str?

Phoenix

Где об этом в документации написано?
Экспериментально, работает std::string, char*
а shared_array<char> не работает
 

    res = get_bytes_in_next_portion4(buf)
Boost.Python.ArgumentError: Python argument types in
    _cfastproto.get_bytes_in_next_portion4(str)
did not match C++ signature:
    get_bytes_in_next_portion4(class boost::shared_array<char>)

ДОкументация здесь смотрю:
http://www.boost.org/doc/libs/1_49_0/libs/python/doc/v2/refe...
ну и подпись "Revised 26 August, 2003 " не вызывает доверия.

Phoenix

Спасибо! с custom_string_to_python_str я ещё как-то смог по форумам нарыть, а вот с обратным как-то не осилил.

// Convert obj_ptr into a QString
static void construct(
PyObject* obj_ptr,
boost::python::converter::rvalue_from_python_stage1_data* data)
{
// Extract the character data from the python string
const char* value = PyString_AsString(obj_ptr);

// Verify that obj_ptr is a string (should be ensured by convertible
assert(value);

// Grab pointer to memory into which to construct the new QString
void* storage = (
(boost::python::converter::rvalue_from_python_storage<QString>*)
data)->storage.bytes;


// in-place construct the new QString using the character data
// extraced from the python object
new (storage) QString(value);

// Stash the memory chunk pointer for later use by boost.python
data->convertible = storage;
}

Это что за магия?
     Он отдаёт кусок памяти из некоторой своей кучи, но какого она будет размера (sizeof(QString) ? а как передаётся это значение?) Потом туда прописывается QString, а сами данные где? QString(value) - здесь сам выделит память?
 (http://misspent.wordpress.com/2009/09/27/how-to-write-boost-python-converters/ - вот здесь исходники полностью есть с QString)
Я пока так сделал, чтобы лишний раз память не выделять.
функция ищет первое вхождение байта со старшим битом равным 1.

int get_bytes_in_next_portion3(std::string buf)
{
int i;
int len = buf.length;
for(i=0;i<len;i++)
if buf[i] & 128) != 0)
break;
return i;
}

int get_bytes_in_next_portion5(PyObject *py_str)
{
if (!PyString_Check(py_str
PyErr_SetString(PyExc_RuntimeError, "not str!");

Py_INCREF(py_str);

int len = PyString_GET_SIZE(py_str);
char *ptr = PyString_AS_STRING(py_str);
int i;
//for(i=0;buf[i] != '\0';i++)
for(i=0; i < len ;i++)
if ptr[i]) & 128) != 0)
break;
Py_DECREF(py_str);
return i;
}
int get_bytes_in_next_portion4(PyObject *py_str)
{
Py_INCREF(py_str);
int len = PyString_GET_SIZE(py_str);
char *ptr = PyString_AS_STRING(py_str);
for(i=0; i < len ;i++)
if ptr[i]) & 128) != 0)
break;
Py_DECREF(py_str);
return i;
}

BOOST_PYTHON_MODULE (_csomemodule)
{
using namespace boost::python;

def("get_bytes_in_next_portion4", get_bytes_in_next_portion4);
}


   
 
[2]done in 125,312,500 nsec // на питоне
[3]done in 2,812,500 nsec // std::string
[4]done in 2,031,250 nsec
[5]done in 1,953,125 nsec // ? добавили проверку на строку, стала работать быстрее.
[6]done in 4,296,875 nsec
[7]done in 5,078,125 nsec
  

6,7 - разные мои реализации передачи custom string. сильно хуже получилось, чем std::string.
Почему 5 работает быстрее, чем 4 совсем не понятно. (хотя разница небольшая, скорей всего погрешность просто).

Dasar

быстрее всего будет через разбиение строки на 16-байтовые выровненные порции и использование sse (может помочь функция _mm_movemask_epi8 или аналог)
Оставить комментарий
Имя или ник:
Комментарий: