在cython中使用访问器语法来处理cpp类。

问题描述 投票:0回答:1

如果我有一个用C++定义的类,如下所示

class sample
{
private:
    int data;
public:
    sample()
    {
        data=0;
    }

    int get_data()
    {
        return data;
    }

    void set_data(int data)
    {
        this->data = data;
    }
};

的类,我想把它暴露在cython代码中。

cdef extern from "sample.cpp":
    cdef cppclass sample:
        sample() except +
        int get_data()
        void set_data(int n)

有没有办法把类中的getter和setter暴露出来 这样就可以在cython中使用了

a = obj.data

而不是

a = obj.get_data()

我知道可以通过包装cython定义的类来实现,但我想避免这种情况,避免这种开销。

也许我的要求太高了。

c++ python-3.x cython accessor
1个回答
2
投票

声明:我不懂cython,所以我不能说下面的内容对cython是否适用。然而,我的策略是通过以下方式实现访问。s.data 已经在C++代码中,以保持绑定的纤细和直接。

C++没有属性,但人们可以模仿它们。

#include <iostream>

template <typename T,typename M,M (T::*getter)(),void (T::*setter)(M)>
struct Attribute {
    T* parent;
    Attribute(T* parent) : parent(parent){}
    operator M() const {
        return (parent->*getter)();
    }
    void operator=(const M& m){
        (parent->*setter)(m);
    }

};

class sample
{
private:
    int data_;
public:

    sample()
    {
        data_=0;
    }    

    int get_data()
    {
        return data_;
    }

    void set_data(int data_)
    {
        this->data_ = data_;
    }
    Attribute<sample,int,&sample::get_data,&sample::set_data> data{this};
};

int main() {
    sample s;
    s.data = 42;
    std::cout << s.data;
}

输出是 42. 请注意,我必须假设一个 int 参数的设置器。也要启用 const int& 需要更多一点。


2
投票

使用上面@idclev 463035818接受的回复中的c++样例类的定义,为了方便,复制到这里。

#include <iostream>

template <typename T,typename M,M (T::*getter)(),void (T::*setter)(M)>
struct Attribute {
    T* parent;
    Attribute(T* parent) : parent(parent){}
    operator M() const {
        return (parent->*getter)();
    }
    void operator=(const M& m){
        (parent->*setter)(m);
    }

};

class sample
{
private:
    int data_;
public:

    sample()
    {
        data_=0;
    }    

    int get_data()
    {
        return data_;
    }

    void set_data(int data_)
    {
        this->data_ = data_;
    }
    Attribute<sample,int,&sample::get_data,&sample::set_data> data{this};
};

我测试了在cython中用一个扁平的公共属性来声明那个C++类,然后... ...它成功了!这样就可以了。

cdef extern from "sample.cpp":
    cdef cppclass sample:
        sample() except +
        int data

测试了一下,并对例子中的访问器进行了仪器测试,显示访问器被正确调用。

非常感谢大家! 那是 有帮助的。

© www.soinside.com 2019 - 2024. All rights reserved.