首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用模板记录C -> C++蹦床函数宏

使用模板记录C -> C++蹦床函数宏
EN

Code Review用户
提问于 2014-11-12 00:17:37
回答 1查看 1.1K关注 0票数 3

我正在重新处理PyCXX (C++包装器用于Python)。

我目前正在研究以下宏代码,并想知道是否有一种使用模板而不是宏来编写它的方法。

如果是这样的话,问题就变成了:写它的最好方法是什么?(与笨拙的模板解决方案相比,我个人更喜欢简洁的宏解决方案)。

代码语言:javascript
复制
#define PYCXX_NOARGS_METHOD_NAME( NAME ) _callNoArgsMethod__##NAME
#define PYCXX_VARARGS_METHOD_NAME( NAME ) _callVarArgsMethod__##NAME
#define PYCXX_KEYWORDS_METHOD_NAME( NAME ) _callKeywordsMethod__##NAME

// - - -

#define PYCXX_DECLARE_METHOD( THIS_CLASS, METHOD_NAME, Ax, NAME_OF_THIS_STATIC_METHOD, ... ) \
    \
    static PyObject* NAME_OF_THIS_STATIC_METHOD( PyObject* _pyObj_caller, PyObject* _a, PyObject* _k ) \
    { \
        DBG_LINE( Ax << #NAME_OF_THIS_STATIC_METHOD << Ax ); \
        try \
        { \
            Py::PythonClassInstance* base_cxx_obj   = reinterpret_cast< Py::PythonClassInstance* >( _pyObj_caller ); \
            THIS_CLASS*              this_class_obj = reinterpret_cast< THIS_CLASS* >             ( base_cxx_obj->m_pycxx_object ); \
            Py::Object result{  (this_class_obj -> METHOD_NAME)(__VA_ARGS__)  }; /* __VA_ARGS__ uses _a and _k (see below) */ \
            return Py::new_reference_to( result.ptr() ); \
        } \
        catch( Py::Exception & ) \
        { \
            DBG_LINE( "! ! !  Exception in PYCXX_DECLARE_METHOD ! ! !" ); \
            return 0; \
        } \
    }

#define PYCXX_NOARGS_METHOD_DECL(   _class, name ) PYCXX_DECLARE_METHOD( _class, name, "  &  "     , PYCXX_NOARGS_METHOD_NAME(   name ) )
#define PYCXX_VARARGS_METHOD_DECL(  _class, name ) PYCXX_DECLARE_METHOD( _class, name, "  & &  "   , PYCXX_VARARGS_METHOD_NAME(  name ), Py::Tuple{_a} )
#define PYCXX_KEYWORDS_METHOD_DECL( _class, name ) PYCXX_DECLARE_METHOD( _class, name, "  & & &  " , PYCXX_KEYWORDS_METHOD_NAME( name ), Py::Tuple{_a}, _k?Py::Dict{_k}:Py::Dict{} )

..。和

代码语言:javascript
复制
#define PYCXX_ADD_METHOD( py_name, method_name, docs, flags ) \
    add_method( \
               #py_name, \
               (PyCFunction)method_name, \
               flags, \
               docs \
               )

#define PYCXX_ADD_NOARGS_METHOD(   py_name, name, docs )  PYCXX_ADD_METHOD( py_name, PYCXX_NOARGS_METHOD_NAME(   name ), docs, METH_NOARGS )
#define PYCXX_ADD_VARARGS_METHOD(  py_name, name, docs )  PYCXX_ADD_METHOD( py_name, PYCXX_VARARGS_METHOD_NAME(  name ), docs, METH_VARARGS )
#define PYCXX_ADD_KEYWORDS_METHOD( py_name, name, docs )  PYCXX_ADD_METHOD( py_name, PYCXX_KEYWORDS_METHOD_NAME( name ), docs, METH_VARARGS | METH_KEYWORDS )

它在类中用于向Python公开某些方法:

代码语言:javascript
复制
Py::Object new_style_class_func_noargs( void )
{
    std::cout << "new_style_class_func_noargs Called."           << std::endl << std::endl;
    std::cout << "value ref count " << m_value.reference_count() << std::endl << std::endl;
    return Py::None();
}
PYCXX_NOARGS_METHOD_DECL( new_style_class, new_style_class_func_noargs )

static void init_type(void)
{
    :
    PYCXX_ADD_NOARGS_METHOD(    func_noargs , new_style_class_func_noargs,  "docs for func_noargs"  );
}

这种架构的原因是Python只能将"extern C“样式的函数放入其表中。但是这段代码试图运行C++实例成员函数。

因此,它必须跳过静态成员函数(就像静态成员函数类型转换为"extern C“样式函数一样)。

对于我们希望公开的每个方法,我们都需要一个单独的静态成员函数。

有什么方法可以使用模板来完成这个任务吗?

EN

回答 1

Code Review用户

回答已采纳

发布于 2014-11-14 21:51:19

令人惊讶的是(至少对我来说)有一个模板解决方案。

看来有可能做到:

代码语言:javascript
复制
template<FuncSignature funcPointer>
myFunc(){...}

后来:

代码语言:javascript
复制
x = myFunc<&MyClass::MyMethod>

你可以在这里找到线索:https://stackoverflow.com/questions/26934036/coding-static-to-instance-method-trampoline-function-with-templates

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/69545

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档