【游戏编程扯淡精粹】使用Swig为cyclone导出Python接口
2020年9月23日
swig还是不满足Zelo的需求,基本是个黑箱,不可控,源码也改不动,所以最后还是换Lua方案了
问题汇总
- .i配置不可控,黑箱
- ParticleForceRegistry 和 ForceRegistry的remove和clear是空的,哑的
需求
当时的需求很简单,为cyclone导出python接口
cyclone是一个物理引擎库,没有依赖,全部手写,所以非常适合实验C++导出脚本接口
zoloypzuo/cyclone: 《游戏物理引擎开发》源码魔改
文档
Swig原理
用.i文件为你生成c++的wrapper代码
然后你用源文件+wrapper编译出dll(pyd)
Swig内置了一个C Parser,解析头文件得到信息
接受.i这个DSL去做代码生成,代码生成直接用目标语言的C API,加上Swig的一套模板代码,生成最终的wrapper代码
其实就是代替人去写C API wrapper
环境配置
PYTHON_INCLUDE:将其设置为包含Python.h的目录
PYTHON_LIB:将其设置为Python库,包括链接路径
使用Python 2.1.1的示例:
PYTHON_INCLUDE:D:\python21\include
PYTHON_LIB:D:\python21\libs\python21.lib
测试流程
拿example里的demo作为流程测试
- swig生成wrapper代码
- 创建VS项目,链接Python
- 编译,得到example.pyd
- 脚本测试
swig.exe -c++ -python Examples\python\callback\example.i
ImportError: DLL load failed: %1 不是有效的 Win32 应用程序。
python27是win32版本的
你编译了一个x64的dll当然不行
example清单
- 简单。一个最小的示例,说明如何使用SWIG来包装C函数,全局变量和常量。常数。这说明预处理器宏和某些C声明如何转换为常量。
- 变量。显示如何从Python访问C全局变量的示例。
- 值。如何通过值传递和返回结构。
- 上课。包装一个简单的C++类。
- 引用。C++引用。
- 指针。简单的指针处理。
- 函数指针
=== 为cyclone编写swig接口
cyclone接口
// cyclone.h
#include "precision.h"#include "core.h"
#include "random.h"
#include "particle.h"
#include "body.h"
#include "pcontacts.h"
#include "pworld.h"
#include "collide_fine.h"
#include "contacts.h"
#include "fgen.h"
#include "joints.h"
Swig build log
include\cyclone\core.h(192) : Warning 389: operator[] ignored (consider using %extend)include\cyclone\core.h(199) : Warning 389: operator[] ignored (consider using %extend)
include\cyclone\core.h(496) : Warning 312: Nested union not currently supported (ignored).
include\cyclone\fgen.h(434) : Warning 325: Nested struct not currently supported (ForceRegistration ignored)
include\cyclone\joints.h(65) : Warning 321: 'set' conflicts with a built-in name in python
include\cyclone\fgen.h(106) : Warning 401: Nothing known about base class 'ParticleForceGenerator'. Ignored.
改了一些配置,主要是为了兼容