py 调用 c(1)
(未完成,暂时搁置)
回顾
py 调用 c(0) - 土星环的基地 里介绍了动态库的生成方式和ctypes 方法直接调用dll文件。
其中动态库的生成是必须的,任何一种合理的调用都是在使用动态库。直接调用源码被我认为是不合理的,所以这方面必须优先学习。
这里会提及另一种方法调用c语言动态库,在python里这种方法将更加合理——pybind11。使用这种方法将真正生成 pyd 文件,并像调用一个真正的软件包一样调用我们的 c 语言代码。
只不过相比ctypes 方法会复杂很多,简单地使用建议还是ctypes 吧。
python 的 pybind11 方式
功能介绍
- pybind11 将 C++ 的数据类型映射到 python 类型,大多数类型都有支持。
- pybind11 将 C++ 的异常映射到 python 异常。
- pybind11 使用模板编程和元编程技术来自动生成 Python 可以调用的 C++ 代码。
- pybind11 使用一些底层技术直接调用函数而非接口。据说是比 dll 调用快很多倍。
- 以及一些其他的特性
基于以上的基础功能,我们需要编写一个兼容层代码,将诸多函数、常量绑定到 python 的命名空间中,并借助 pybind11 以及 python pack 进行一次编译(任意方式比如 cmake)。即可得到 pyd 文件。
编写兼容层
我们不要更改调用的原库,而是应该新建一个 C++ 工程并调用原库的动态库,以下仅说明 cmake 方法。只要在 CMakeLists 中增加类似的代码,并将 .a 和 .dll 文件放在合适的位置,就可以链接进兼容层项目。其他编译方法都类似,不再赘述。
target_link_libraries(modbus_binding PRIVATE "${CMAKE_SOURCE_DIR}/lib/libmodbusx_shared.a")
而 C++ 兼容层中,必须为每个你期望调用的函数系列单独建立一个类,并且在兼容层管理好内存。
Note暂时搁置,在尝试 parasoft 测试