Shiboken入门练习

来源:互联网 发布:chinaz 源码 编辑:程序博客网 时间:2024/06/05 16:55

终于弄清楚shiboken怎么用了,可是距离学习使用Python调用C模块已经过了10个月时间。

不管怎样,第一个例子,还是需要完整记录一下,备忘。

(注意:本文只是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#endifclass 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 = libTARGET = fooHEADERS += foo.hSOURCES += foo.cppDEFINES += LIBFOO_BUILD

运行 qmake 和 nmake 生成 foo.lib 和 foo.dll

生成胶水文件

需要准备的文件:

+-- foobinding/|      |-- global.h|      `-- typesystem_foo.xml
  • global.h 包含要提取的接口的头文件
#include "foo.h"
  • typesystem_foo.xml 包含要提取的信息
<?xml version="1.0"?><typesystem package="foo">    <primitive-type name="int"/>    <value-type name='Math'/></typesystem>

包的名字取为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 unittestimport fooclass 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相比,易用性还是远远不够

参考

  • http://hi.baidu.com/cyclone/blog/item/8ee887d618722c2207088b1a.html

  • http://developer.qt.nokia.com/wiki/PySide_Binding_Generation_Tutorial%3A_Module_2_Binding_libfoo_using_Shiboken

 

原创粉丝点击