Python API的类型

分为High Level API和Low Level API。
Low Level API是API的基础,调用High Level API时,Python基础库会为C/C++程序创建全局的运行环境。

例子

class ScapyAdapter
{
private:
    ScapyAdapter()
    {
        Py_Initialize();
        py_global_object = PyModule_GetDict(PyImport_AddModule("__main__"));

        PyRun_SimpleStringFlags("from scapy import *", nullptr);
        PyRun_SimpleStringFlags("from scapy.layers.inet import *", nullptr);
        PyRun_SimpleStringFlags("from scapy.layers.inet6 import *", nullptr);
        PyRun_SimpleStringFlags("from scapy.layers.ppp import *", nullptr);
        PyRun_SimpleStringFlags("from scapy.layers.vxlan import *", nullptr);
        PyRun_SimpleStringFlags("from scapy.contrib.nsh import *", nullptr);
    }

    static std::shared_ptr<ScapyAdapter> ptr_instance_;
    struct PyObjectDeleter
    {
        void operator()(PyObject * obj) const { if (obj) Py_DECREF(obj); }
    };

    using PyObjectPtr = std::unique_ptr<PyObject, PyObjectDeleter>;
    PyObject * py_global_object{nullptr};

public:
    virtual ~ScapyAdapter()
    {
        if (PyErr_Occurred())
        {
            PyErr_Print();
            PyErr_Clear();
        }

        Py_Finalize();
    }

    ssize_t ConstructPacket(const char * expr, char * buffer, size_t sz_buffer)
    {
        char cstr_expr[4096];
        snprintf(cstr_expr, sizeof(cstr_expr), "pkt_object=%s", expr);

        PyObjectPtr py_expr_object = PyObjectPtr(PyRun_StringFlags(cstr_expr, Py_single_input,
            py_global_object, py_global_object, nullptr));

        if (py_expr_object == nullptr)
        {
            PyErr_Print();
            PyErr_Clear();
            return -1;
        }

        PyObjectPtr py_pkt_object = PyObjectPtr(PyDict_GetItemString(py_global_object, "pkt_object"));
        if(py_pkt_object == nullptr)
        {
            PyErr_Print();
            PyErr_Clear();
            return -2;
        }

        PyObjectPtr py_pkt_bytes = PyObjectPtr(PyObject_Bytes(py_pkt_object.get()));
        const char * pkt_ptr = PyBytes_AsString(py_pkt_bytes.get());
        unsigned int pkt_len = PyBytes_Size(py_pkt_bytes.get());

        memcpy(buffer, pkt_ptr, pkt_len);
        return pkt_len;
    }

    static std::shared_ptr<ScapyAdapter> ScapyAdapterInstance()
    {
        if(ptr_instance_ != nullptr)
            return ptr_instance_;

        ptr_instance_ = std::shared_ptr<ScapyAdapter>(new ScapyAdapter());
        return ptr_instance_;
    }
};

需要注意的问题


luqiuwen
34 声望0 粉丝