py++

昨日の続き。py++を使ってみる。

py++をセットアップ

gccxml
  • gccxml-0.9.0-win32-x86.exeをダウンロードしてsetup
    • デフォルトでinstallパスのフォルダ名が'gccxml 0.9'になってた。気持ち悪いので'gccxml-0.9'に変更。
  • msvc対応→bin/に移動して'gccxml_vcconfig.exe ..\share\gccxml-0.9\VcInstall .'を実行→Vc9を作る。
    • 環境によってはbinフォルダの横だと動かなかった。share/gccxml-0.9に移動(上書き?)すると動いた。
  • 環境設定→GCCXML_COMPILER=msvc9
pygccxml
  • pygccxml-1.0.0.zipをダウンロード
  • python setup.py install
py++
  • pyplusplus-1.0.0.zipをダウンロード
  • python setup.py install

使ってみる

http://svn.sourceforge.jp/svnroot/shive/junk/diary/2009/20091217_pyplusplus.tar.gz
sconsからpy++を呼び出してbindingを生成してpydビルドに混ぜ込む。

from os import environ, path
from distutils.sysconfig import get_python_inc, get_python_lib

def build_bindings(target, source, env):
    '''py++でバインディングを生成'''
    from pyplusplus import module_builder
    mb = module_builder.module_builder_t(
        map(lambda s: path.relpath(str(s), '.obj'), source),
        working_directory='.obj',
        include_paths=[],
        compiler = 'msvc9' )
    mb.build_code_creator(module_name = 'person')
    mb.write_module(str(target[0]))
build_bindings_action = Builder(action = build_bindings)

# 環境設定
env = Environment(
    BUILDERS = {'Binding': build_bindings_action},
    CPPFLAGS  = ['/O2', '/MD', '/EHsc', '/Zi', '/Fd.obj/vc90.pdb', '/FIstdafx.h'],
    CPPPATH = [ environ['BOOST_INC'], get_python_inc() ],
    LIBPATH = [ environ['BOOST_LIB'], get_python_lib(standard_lib = True) + 's' ],
    LINKFLAGS = ['/nologo', '/debug'],
    SHLIBSUFFIX = '.pyd' )
env.VariantDir('.obj', 'src')

# プリコンパイルヘッダ
env['PCHSTOP'] = 'stdafx.h'
env['PCH'] = env.PCH('.obj/stdafx.cpp')[0]

# py++
bindings = env.Binding('.obj/bindings.cpp', '.obj/person.h')

# pythonモジュールのビルド
src = ['.obj/person.cpp', bindings]
pyd = env.SharedLibrary('.obj/person.pyd', src)
env.AddPostAction(pyd, Copy('.', pyd[0].get_abspath()))
env.Clean(pyd, ['.obj', 'person.pyd'])
env.Default(pyd)

# test
test = env.Command('test', pyd, 'python test.py')

test

from person import *

class Human(Person):
    def __init__(self):
        super(Human, self).__init__()
    def _what(self):
        return 'human!!'

person = Person()
print type(person)
person.say()

human = Human()
print type(human)
human.say()

other = Person()
print type(other)
other.say()

other = person
print type(other)
other.say()
$ scons -Q test
python test.py
<class 'person.Person'>
[00CD37D8]person!!
<class '__main__.Human'>
[00CD4810]human!!
<class 'person.Person'>
[00CD4990]person!!
<class 'person.Person'>
[00CD37D8]person!!

ちゃんとvirtualのoverrideも自動でやってくれてます。これは良い。