python 扩展c extention

首先我们会使用PyMODINIT_FUNC 和PyMethodDef 进行创建c的扩展。
关于PyMethodDef可以的参数含义可以在官网查看

第一步

// 简单的say hello 函数
static PyObject* say_hello(PyObject* self, PyObject* args) {
    const char* name;
    if (!PyArg_ParseTuple(args, "s", &name))
        return NULL;

    printf("Hello %s!\n", name);

    Py_RETURN_NONE;
}

// lambda 函数调用
void set_seed(int seed) {
    printf("seed %d!\n", seed);
}



// PyMethodDef methods 函数
static void init_module(PyModuleDef* mdef, PyObject* m) {
    mdef->m_doc = "Inner c++ core of test";
    typedef PyObject* (*Myds)(PyObject*,PyObject**,int64_t,PyObject*);

    static PyMethodDef methods[] = {
            {"hello", (PyCFunction)say_hello, METH_VARARGS, NULL},
             // lambda 函数
            { "lambda_hello",
              (PyCFunction)(Myds)[](PyObject* self, PyObject** args, int64_t n, PyObject* kw) -> PyObject* {
                try {
                    uint64_t arg_filled=0;
                    (void)arg_filled;
                    if (n+(kw?Py_SIZE(kw):0)<=1 && n+(kw?Py_SIZE(kw):0)>=1 && PyLong_CheckExact(args[0])) {
                        int arg0 = PyLong_AsLong(args[0]);
                        //!PyErr_Occurred();
                        if (kw) {
                            auto kw_n = Py_SIZE(kw);
                            for (int i=0; i<kw_n; i++) {
                                auto ko = PyTuple_GET_ITEM(kw, i);
                                auto vo = args[i+n];
                                auto ks = PyUnicode_AsUTF8(ko);
                                uint khash = leetcode::hash(ks);

                                if (khash == 16948695u) {
                                    // hash match seed
                                    CHECK((PyLong_CheckExact(vo)));
                                    arg0 = PyLong_AsLong(vo);
                                    arg_filled |= 1ull << 0;
                                    continue;
                                }

                                LOGf << "Not a valid keyword:" << ks;
                            }
                        }
                        return GET_PY_NONE((set_seed(arg0)));
                    }
                } catch (const std::exception& e) {
                    std::stringstream ss;
                    ss  << "Wrong inputs arguments";
                    PyErr_Format(PyExc_RuntimeError,
                                 "%s\n%s\nFailed reason:%s",
                                 ss.str().c_str(),
                                 R""(The function declarations are:
                                 void lambda_hello(int seed)
                                 )"",
                                 e.what()
                    );
                }
                return nullptr;

            },
            METH_FASTCALL | METH_KEYWORDS,
                    R""(Document:
                        lambda_hello
                        Declaration:
                        void lambda_hello(int seed))""
             },
            {NULL, NULL, 0, NULL}
    };
    PyModule_AddFunctions(m, methods);
}

// 定义Extention的入口 PyMODINIT_FUNC
#define PYJF_MODULE_INIT(name) \
PyMODINIT_FUNC PyInit_##name() { \
    PyObject *m; \
    try { \
        PyModuleDef *def = new PyModuleDef(); \
        memset(def, 0, sizeof(PyModuleDef)); \
        def->m_name = #name; \
        def->m_doc = ""; \
        def->m_size = -1; \
        Py_INCREF(def); \
        m = PyModule_Create(def); \
        init_module(def, m); \
    } catch(const std::exception& e) { \
        PyErr_SetString(PyExc_RuntimeError, e.what()); \
        return nullptr; \
    } \
    return m; \
}

// 声明
PYJF_MODULE_INIT(example_name)

详细的项目代码见github

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝鲸123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值