Skip to content

def_buffer doesn't accept pointer-to-member-function #857

Closed
@bmerry

Description

@bmerry

Issue description

The implementation of def_buffer directly calls the passed function or function object, so a pointer-to-member-function causes compilation errors.

I'll provide a PR to fix it (I've got some code that should work, just need to add a regression test).

Reproducible example code

#include <pybind11/pybind11.h>
#include <cstdint>

namespace py = pybind11;

class A {
public:
    int32_t data = 0;

    py::buffer_info get_buffer_info()
    {
        return py::buffer_info(
            &data, sizeof(data),
            py::format_descriptor<decltype(data)>::format(),
            1);
    }
};

PYBIND11_PLUGIN(_buffer) {
    py::module m("_buffer");

    py::class_<A>(m, "A", py::buffer_protocol())
        .def(py::init<>())
        .def_readwrite("data", &A::data)
        .def_buffer(&A::get_buffer_info);

    return m.ptr();
}

Output (GCC 5.4):

    In file included from buffer.cpp:1:0:
    /home/bmerry/work/sdp/env/include/site/python2.7/pybind11/pybind11.h: In instantiation of ‘pybind11::class_<type_, options>::def_buffer(Func&&)::<lambda(PyObject*, void*)> [with Func = pybind11::buffer_info (A::*)(); type_ = A; options = {}; PyObject = _object]’:
    /home/bmerry/work/sdp/env/include/site/python2.7/pybind11/pybind11.h:1014:31:   required from ‘struct pybind11::class_<type_, options>::def_buffer(Func&&) [with Func = pybind11::buffer_info (A::*)(); type_ = A; options = {}]::<lambda(PyObject*, void*)>’
    /home/bmerry/work/sdp/env/include/site/python2.7/pybind11/pybind11.h:1014:9:   required from ‘pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_buffer(Func&&) [with Func = pybind11::buffer_info (A::*)(); type_ = A; options = {}]’
    buffer.cpp:25:40:   required from here
    /home/bmerry/work/sdp/env/include/site/python2.7/pybind11/pybind11.h:1018:67: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘((pybind11::class_<type_, options>::def_buffer(Func&&) [with Func = pybind11::buffer_info (A::*)(); type_ = A; options = {}]::capture*)ptr)->pybind11::class_<type_, options>::def_buffer(Func&&) [with Func = pybind11::buffer_info (A::*)(); type_ = A; options = {}]::capture::func (...)’, e.g. ‘(... ->* ((pybind11::class_<type_, options>::def_buffer(Func&&) [with Func = pybind11::buffer_info (A::*)(); type_ = A; options = {}]::capture*)ptr)->pybind11::class_<type_, options>::def_buffer(Func&&) [with Func = pybind11::buffer_info (A::*)(); type_ = A; options = {}]::capture::func) (...)’
                 return new buffer_info(((capture *) ptr)->func(caster));

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions