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_;
}
};
需要注意的问题
- 调用PyRun_StringFlags()时,需要填写start参数。该参数在compiler.h中定义,其意义在https://docs.python.org/3/c-api/veryhigh.html文档中有解释说明。
- 在调用Py_Finalize()之前,要注意清除所有由Python解释器抛出的异常,否则会出错。
- 在Python官网上,High level API的文档、例子不是很全,特别是需要与Low Level API结合时。可以参考https://hg.python.org/cpython/file/tip/Python/pythonrun.c
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。