注意:本文只是windows下使用shiboken的一个尝试,正常使用参考:使用Shiboken为C++和Qt库创建Python绑定 )
生成C++动态库
写个很简单的类:
+-- libfoo/
| |-- foo.h
| |-- foo.cpp
| `-- foo.pro
foo.h内容如下:
#ifndef FOO_H
#define FOO_H
#if defined _WIN32
#if LIBFOO_BUILD
#define LIBFOO_API __declspec(dllexport)
#else
#define LIBFOO_API __declspec(dllimport)
#endif
#else
#define LIBFOO_API
#endif
class LIBFOO_API Math
{
public:
Math(){}
~Math(){}
int squared(int x);
};
#endif // FOO_H
foo.cpp 内容如下:
#include "foo.h"
int Math::squared(int x)
{
return x * x;
}
使用qmake来管理工程,对应的foo.pro 如下
TEMPLATE = lib
TARGET = foo
HEADERS += foo.h
SOURCES += foo.cpp
DEFINES += LIBFOO_BUILD
运行 qmake 和 nmake 生成 foo.lib 和 foo.dll
生成胶水文件
需要准备的文件:
+-- foobinding/
| |-- global.h
| `-- typesystem_foo.xml
global.h
包含要提取的接口的头文件
#include "foo.h"
typesystem_foo.xml
包含要提取的信息
包的名字取为foo,要导出的类为Math,类中用到了
int 这一个基本类型。
然后在该目录下运行shiboken(生成胶水代码):
shiboken global.h --include-paths=../libfoo typesystem_foo.xml --output-directory=.
由于我们的 foo.h
不在该目录下,故需要指定其所在目录(--include-paths)。
在当前目录下,最终将生成以下文件:
foo/foo_python.h
foo/foo_module_wrapper.cpp
foo/math_wrapper.h
foo/math_wrapper.cpp
胶水代码生成以后,我们就可以调用编译器进行编译:
编译胶水文件
+-- libfoo/
| |-- foo.h
| |-- foo.cpp
| |-- foo.pro
| |-- foo.dll
| `-- foo.lib
|
+-- foobinding/
| |-- global.h
| |-- typesystem_foo.xml
| |
| +---foo/
| |-- foo_python.h
| |-- foo_module_wrapper.cpp
| |-- math_wrapper.h
| `-- math_wrapper.cpp
首先看看编译这几个胶水文件需要哪些东西:
头文件路径
库文件
python
python27.lib
shiboken
shiboken-python2.lib
foo
foo.lib
直接调用MSVC的编译器进行编译:
cl /EHsc /LD foo/foo_module_wrapper.cpp foo/math_wrapper.cpp /ID:/python27/include /ID:/shiboken/dist/include/shiboken /I../libfoo /Fefoo.pyd /link /LIBPATH:D:/python27/libs /LIBPATH:D:/shiboken/dist/lib /LIBPATH:../libfoo/release shiboken-python2.7.lib python27.lib foo.lib
生成 foo.pyd
测试
编译一个Python程序测试看看:
# -*- coding: utf-8 -*-
import unittest
import foo
class MathTest(unittest.TestCase):
def testMath(self):
'''Test case for Math class from foo module.'''
val = 5
math = foo.Math()
self.assertEqual(math.squared(5), 5 * 5)
if __name__ == '__main__':
unittest.main()
恩一切正常。
至此,已经全手动的过了一遍,如果要自动化,看来还是要继续好好学习cmake才行。
顺便抱怨一下,PySide 的 shiboken
和PyQt4的sip相比,易用性还是远远不够
参考