python用api调用c语言_在C/C++程序中调用High Level的Python API

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 ptr_instance_;

struct PyObjectDeleter

{

void operator()(PyObject * obj) const { if (obj) Py_DECREF(obj); }

};

using PyObjectPtr = std::unique_ptr;

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 ScapyAdapterInstance()

{

if(ptr_instance_ != nullptr)

return ptr_instance_;

ptr_instance_ = std::shared_ptr(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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值