很多系统为了担保数据在系统高下游的自动校验,避免数据构造非常带来的系统稳定性问题,都会用 json 格式进行数据交互,可以采取 json-schema 来定义 json接口 ,并利用 json-schema-validator 来校验接口相应的构造的合法性。
然而系统中不同子系统的实现(编程措辞)并非总是同等,虽然各种措辞都供应了 json-schema-validator 的详细实现,但是不同措辞支持的 json-schema-validator 标准的版本并非完备同等,这会对后续的利用带来一些混乱,例如:
目前大多数措辞,例如:Java, Golang, Php, Python, Lua等都支持C/C++的扩展。因此,可以用C/C++来为其他措辞供应统一的扩展库支持,本文便是先容怎么利用 Boost::Python 库供应 json-schema-validator 的Python支持,并先容如何利用 distutils 来编译&分发Python库。

Python调用C/C++的办法
有两种办法可以实现Python调用C/C++编写的库:
ctypes
ctypes加载so文件
ctype 是Python的外部函数库。它供应了C兼容的数据类型,并许可在DLL或共享库中调用函数。
ctype 是Python封装的API函数库。个中 cdll = <ctypes.LibraryLoader object> 是一个库加载器工具,调用 cdll.LoadLibrary 便可调用C/C++的so库。
此处不再对如何利用 ctype 模块加载so文件做过多的先容,详细可以参考其 官方文档 。
利用Python扩展该办法是Python为整合其它措辞而供应的一种扩展机制,并且该机制不局限于C/C++,也可以用于其它措辞。Python的可扩展性具有如下的优点:
方便为措辞增加新功能具有可定制性可以实当代码复用……该办法的详细利用此处也不再做过多先容,详细信息可以直接参考Python的官方文档 Building C and C++ Extensions 来理解。接下来要讲的例子便是利用了 可以实当代码复用 的优点。
如 Building C and C++ Extensions 所示,Python供应了 Python/C++ API 用来实现Python和C++的交互。然而,直策应用这些API来完成Python和C/C++的交互还是会存在很多重复事情的。 Boost::Python 则对 Python/C++ API 进行了抽象和包装,从而使得Python和C++的交互更加方便。
Boost::Python封装C/C++扩展接下来我们先容我们是如何利用Boost::Python来为 nlohmann_json_schema_validator 增加Python扩展。
nlohmann_json_schema_validator is a C++ library for validating JSON documents based on a JSON Schema which itself should validate with draft-7 of JSON Schema Validation .
编译nlohmann json schema validator库nlohmann json schema validator 支持产出可实行的bin文件以及可供其他项目利用的动态库。为了可以将该扩展包装成Python扩展,我们须要天生该库的动态库。
首先根据 nlohmann json schema validator 的 编译文档 编译出 nlohmann json schema validator 的动态库。
Boost::Python封装C/C++代码
在安装Boost的时候,虽然Boost的头文件中存在Boost::Python干系的hpp文件,但是默认却没有该动态库。因此,在利用Boost::Python之前,首先须要安装该库。
$ brew install boost-python3
然后,我们用C++编写 class json_validator_python; 来封装 nlohmann json schema validator 库,并利用Boost::Python来导出,详细如下:
// jsv_python.cpp#include <iomanip>#include <iostream>#include <nlohmann/json-schema.hpp>#include <boost/python.hpp>using namespace boost::python;class JSON_SCHEMA_VALIDATOR_API json_validator_python{private: nlohmann::json_schema::json_validator validator;public: json_validator_python() {} void set_root_schema(const std::string &json_string) { validator.set_root_schema(nlohmann::json::parse(json_string.begin(), json_string.end())); } void validate(const std::string &json_string) const { validator.validate(nlohmann::json::parse(json_string.begin(), json_string.end())); }};// json_schema_validator为module名,必需和天生的so库名一样BOOST_PYTHON_MODULE(json_schema_validator){ class_<json_validator_python, boost::noncopyable> ("json_validator_python") .def("set_root_schema", &json_validator_python::set_root_schema) .def("validate", &json_validator_python::validate) ;}
如上所示的 BOOST_PYTHON_MODULE 代码,目的是导出类及成员方法,这些导出的类和方法可以在Python中调用。
关于Boost::Python更详细的利用,可以参考其 官方文档 。
编译并产出Python扩展g++ --std=c++11 -fPIC -c jsv_python.cpp \-I${json-schema-validator_PATH}/src \-I${nlohmann-json_PATH} \-I${Boost_PATH}/include \-I${Python_INCLUDE_PATH}g++ --std=c++11 -shared \-L${json-schema-validator_LIB_PATH} \-L${Python_LIB_PATH} \-L${Boost_Python_LIB_PATH} \-lnlohmann_json_schema_validator \-lboost_python38 -lpython3.8 \-o json_schema_validator.so jsv_python.o
如上的指令,会天生封装之后的Python扩展: json_schema_validator.so 。
测试python扩展在当前目录实行如下的Python代码,可以创造,我们封装的扩展已经可以当做Python扩展来导入并利用了。
import json_schema_validator as jsvvalidator = jsv.json_validator_python()isValidator = Truetry: validator.set_root_schema('{"type":"object", "properties": {"a":{"type": "string"}}}') validator.validate('{"a":"1"}');except: isValidator = Falseprint(isValidator)
利用distutils编译并分发扩展
为了利用方便,利用 Building C and C++ Extensions 先容的 distutils模块 编译Python扩展。
from distutils.core import setup, Extensionimport osos.environ["CC"] = "g++"os.environ["CXX"] = "g++"module1 = Extension('json_schema_validator', include_dirs = ['../../src', '../../', '/usr/local/Cellar/boost/1.72.0_3/include', '/usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/include/python3.8'], libraries = ['boost_python38', 'python3.8', 'nlohmann_json_schema_validator'], library_dirs = ['/usr/local/opt/python@3.8/Frameworks/Python.framework/Versions/3.8/lib', '/usr/local/Cellar/boost-python3/1.72.0_1/lib', '.'], sources = ['jsv_python.cpp'], extra_compile_args=['--std=c++11'], extra_link_args=['--std=c++11'])setup (name = 'json-schema-validator', version = '1.0', description = 'json schema validator', ext_modules = [module1])
$ python3 setup.py build$ python3 setup.py install$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/python3.7/site-packages/json_schema_validator
然后就可以在任意位置,实行一节的测试代码啦。
大家平时学习Python的时候肯定会碰着很多问题,
领取办法:
如果想获取这些学习资料,先关注我然后私信
如果这篇文章对你有帮助,请记得给我来个评论+转发