请问这样的 C++函数如何用 pybind11 绑定? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Huelse
V2EX    C++

请问这样的 C++函数如何用 pybind11 绑定?

  •  
  •   Huelse 2019-07-15 10:12:46 +08:00 4051 次点击
    这是一个创建于 2347 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我想将以下类中的方法通过 pybind11 绑定到 python 中使用,但无奈看了好一会儿官方文档没有找到合适的例子(可能我眼瞎),所以来 V2 请求各位支招

    class SEALContext { ... static auto Create(const EncryptionParameters &parms, bool expand_mod_chain = true, sec_level_type sec_level = sec_level_type::tc128) { return std::shared_ptr<SEALContext>( new SEALContext( parms, expand_mod_chain, sec_level, MemoryManager::GetPool()) ); } ... } 

    绑定 wrapper.cpp 中我是这么写的能编译通过:

    PYBIND11_MODULE(seal, m) { py::class_<SEALContext>(m, "SEALContext") .def("Create", &SEALContext::Create) } 

    我想在 Python 中 SEALContext.Create(parms)这样调用,经测试,Python 总是提示我需要传入三个参数,但我只想传入 parms 这一个,如果我在 wrapper.cpp 中限定,就编译不通过,然后不知道该怎么做了。。。 感谢各位了!

    18 条回复    2019-07-22 12:38:04 +08:00
    wutiantong
        1
    wutiantong  
       2019-07-15 10:20:23 +08:00   1
    直接用 lambda 定义好了。
    wutiantong
        2
    wutiantong  
       2019-07-15 10:22:04 +08:00   1
    .def("Create", [] (const EncryptionParameters &parms) { return SEALContext::Create(parms); } )

    就像这个样子。
    Huelse
        3
    Huelse  
    OP
       2019-07-15 11:22:31 +08:00
    @wutiantong #2 哇,我还在想这个咋用,感谢!~
    Huelse
        4
    Huelse  
    OP
       2019-07-15 20:16:43 +08:00
    @wutiantong 呃,遇到了个新问题,请问你知道
    ```
    double free or corruption (out)
    Aborted (core dumped)
    ```
    错误怎么处理吗?
    https://github.com/pybind/pybind11/issues/1839
    我按照这个,弄不好呀
    wutiantong
        5
    wutiantong  
       2019-07-16 00:20:17 +08:00   1
    @Huelse double free 广泛存在于 C++程序中,本质上就是对动态申请的内存两次执行 free(),这类问题在很多场景下都可能出现,所以在不清楚你的代码的情况下我是帮不到你的。
    wutiantong
        6
    wutiantong  
       2019-07-16 00:21:18 +08:00   1
    至少你需要定位到程序挂掉的那个位置。
    Huelse
        7
    Huelse  
    OP
       2019-07-16 08:23:37 +08:00
    @wutiantong #5 好的,这个是微软 SEAL 库的源码,我首先想的是我 pybind11 里写的有问题
    wutiantong
        8
    wutiantong  
       2019-07-16 09:38:18 +08:00   1
    @Huelse 我看到那个 issue 原来就是你提的,看到了代码后我发现问题应该是在于:
    key_context_data() 这个方法的返回值类型是 std::shared_ptr<ContextData>,然而你的 binding 并没有做任何 wrapping 处理,并且在 test.py 里直接把它当作 ContextData 来调用了( context.key_context_data().parms() 这行 )
    Huelse
        9
    Huelse  
    OP
       2019-07-16 10:46:44 +08:00
    @wutiantong #8 是的,原谅我第一次接触,我还在想怎么弄
    Huelse
        10
    Huelse  
    OP
       2019-07-16 15:41:00 +08:00
    @wutiantong #8
    pybind11 文档给我的方案有两个,但都好像是要改 c++代码的,我不希望这样。
    https://pybind11.readthedocs.io/en/master/advanced/smart_ptrs.html#std-shared-ptr

    ```
    inline auto key_context_data() const
    {
    auto data = context_data_map_.find(key_parms_id_);
    return (data != context_data_map_.end()) ?
    data->second : std::shared_ptr<ContextData>{ nullptr };
    }
    ```
    我想问题应该是这里的,请问我该怎么做?
    wutiantong
        11
    wutiantong  
       2019-07-16 15:52:18 +08:00   1
    @Huelse

    看起来只需要把
    // SEALContext::ContextData
    py::class_<SEALContext::ContextData>(m, "SEALContext::ContextData")

    改成
    py::class_<SEALContext::ContextData, std::shared_ptr<SEALContext::ContextData>>(m, "SEALContext::ContextData")

    就行了。
    Huelse
        12
    Huelse  
    OP
       2019-07-16 16:38:31 +08:00
    @wutiantong #11 我透,还真是这样!我该怎么感谢你
    wutiantong
        13
    wutiantong  
       2019-07-16 17:11:47 +08:00
    @Huelse 不用谢~
    Huelse
        14
    Huelse  
    OP
       2019-07-17 22:38:09 +08:00
    @wutiantong #13
    尴尬。。这次遇到了`Segmentation fault (core dumped)` 段错误
    又弄不好了
    python 里是这样的
    ```
    evaluator = Evaluator(context)
    ...
    x_encrypted = Ciphertext()
    ...
    x_sq_plus_One= Ciphertext()
    evaluator.square(x_encrypted, x_sq_plus_one)
    ```
    wrapper.cpp 中是
    ```
    py::class_<Evaluator>(m, "Evaluator")
    .def("square", (void (Evaluator::*)(const Ciphertext &, Ciphertext &)) &Evaluator::square)
    ```
    怎么调试都是`Segmentation fault (core dumped)`
    能提供一些意见吗?
    https://github.com/Huelse/pyseal/blob/master/pyseal/wrapper.cpp
    谢谢!
    wutiantong
        15
    wutiantong  
       2019-07-18 10:59:30 +08:00   1
    @Huelse

    x_encrypted = Ciphertext(context)
    x_sq_plus_One= Cipertext(context)

    改成这样试试。
    Huelse
        16
    Huelse  
    OP
       2019-07-18 15:14:46 +08:00
    @wutiantong
    经测试还是不行的,
    好在我发现了是 MemoryPoolHandle()的问题,只需要

    pool = MemoryPoolHandle().New(False)
    evaluator.square(x_encrypted, x_sq_plus_one, pool)

    就可以了,不过还是谢谢您~
    Huelse
        17
    Huelse  
    OP
       2019-07-22 12:24:12 +08:00
    @wutiantong #15
    啊,再打扰下,这种 template 该怎么绑定呢?

    我已包含#include <pybind11/complex.h>
    ```
    template<typename T,
    typename = std::enable_if_t<std::is_same<T, double>::value ||
    std::is_same<T, std::complex<double>>::value>>
    inline void decode(const Plaintext &plain, std::vector<T> &destination,
    MemoryPoolHandle pool = MemoryManager::GetPool())
    {
    ...
    }
    ```

    虽然我把 T 替换成 double 类型可以编译成功,但使用中,函数并不能对这个 vector 做出修改
    ``` error
    .def("decode", (void (CKKSEncoder::*)(const Plaintext &, std::vector<double> &, MemoryPoolHandle)) &CKKSEncoder::decode)
    ```
    谢谢!
    wutiantong
        18
    wutiantong  
       2019-07-22 12:38:04 +08:00
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5613 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 39ms UTC 02:33 PVG 10:33 LAX 18:33 JFK 21:33
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86