4

I got a Python list which I can obtain its pointer and pass this pointer address to C++ to work on

MyPointer = TheList.as_pointer()

now I pass this address to C++ with ctypes

in C++ I can do the following:

*(float*) MyPointer = 2.0f; //for example

and the Python values will update immediatly,now the problem is: how to extend or delete some values (like modify the list directly from C++) as I sense these data are a std::vector how to do push_back and so on to adjust size with a fast way (as iterating in Python is pretty much SLOW)

4
  • 1
    as_pointer seems to be Blender specific as far as I can see … Anyway, a Python list is not implemented as a std::vector, it’s an own data structure. You need to cast your pointer to that data type to work with it. The type is defined in the Python C API. Commented Apr 5, 2013 at 12:24
  • You are better off actually writing a C extension module than using ctypes when you want to use the Python C-API, see docs.python.org/2.7/extending/index.html and docs.python.org/2.7/c-api/list.html Commented Apr 5, 2013 at 12:25
  • @KonradRudolph true it is from Blender Python api :) Commented Apr 5, 2013 at 12:30
  • 1
    If you need fast iteration, you probably want to work with array.array('d') or with numpy.array anyway. They allow efficient packing of floating-point numbers into the array. A Python list, on the other hand, contains (in C++ terminology) pointers to stack-allocated objects, each of which contains a single double. I.e. it's like an std::vector<PyObject*>, where each PyObject* must be dereferenced to get to the underlying double. To append to a single number to a Python list, you must heap-allocate it to get the PyObject*. Commented Apr 5, 2013 at 12:34

1 Answer 1

6

Given only that pointer, you cannot extend the list. What you are passing to C++ is the address of the array internally used to implement the Python list. This cannot be an std::vector, as Python lists are not implemented as STL vectors, but as C-level arrays of Python object references. These arrays do not contain a backpointer to the Python list object.

To mutate the list, take a look at the documentation and link your C++ code with the Python library. If you really must call your C++ function from ctypes, call it with the id of the list to get the pointer to the list, as opposed to its element array. Then you can operate on the list like this:

#include <Python.h>

extern "C"
void append_to_list(uintptr_t lst_id)
{
    PyObject* lst = reinterpret_cast<PyObject*>(ptr);
    PyObject* new_num = PyFloat_FromDouble(2.0);
    if (!new_num) {
        ... PyFloat creation failed ...
    }
    int ret = PyList_Append(lst, new_num);
    Py_DECREF(new_num);
    if (ret) {
        ... PyList_Append failed ...
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

I understand the concept but it gives me when excuting in python a memory error : access violation reading at 0x000
it is failing at PyList_Append
didn't put error checking,but did printf after each line and it didn't print after the PyList_Append
well i didn't check the values (but i know if errors will generate -1 from python documentations) as I found a better way to work without PyObjects (I hate them :D) I casted to a float pointer and worked with it ^_^ still will try to modify its size (don't know how yet)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.