Differences between revisions 1 and 4 (spanning 3 versions)
Revision 1 as of 2006-08-29 06:00:17
Size: 26
Editor: ybeetle
Comment:
Revision 4 as of 2006-12-06 04:50:00
Size: 3787
Editor: ZoomQuiet
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
在这里详述 Pyrex. '''Pyrex与C++混合编程'''
[[TableOfContents]]
Line 3: Line 4:
= 综述 =

以前python想用C++混合编程只能通过
Boost 或 Swig 或是 DIY ,不过这三种方法都有些麻烦,不易控制与扩展。

其实高版本的Pyrex可以与C++混合编程,不过中文社区里好像没有介绍,这也是我写这篇教程的原因。

== 我的教程 ==
附件:教程所用代码下载 attachment:pyxx.rar

=== 准备的条件: ===
{{{
1. Python2.4安装
2. Pyrex安装必须是版本 Pyrex-0.9.4.1 才可以与C++编译
3. Dev-C++ 编译器 (版本最好是 4.9.9.2或以上) Linux 下用 g++ 就行
4. 如果windows下必须要先修正 Python24.lib (在我的例程附件中带有修正后的 Python24.lib 文件)
}}}
   修正PythonXX.lib 方法如下:{{{
 1.拷贝python24.dll 到 C:\Python24\libs 目录下面
 2.在命令行模式下,转到Python 的lib 目录下面
 3.运行下面命令:
  pexports python24.dll >python24.def
  dlltool --dllname python24.dll --def python24.def --output-lib python24.lib

 Python24.dll 在 C:\WINNT\system32\python24.dll 下面。
}}}
上面的条件要先弄好才能开始玩,要不然别怪我教程不对。


=== 说明 ===

只是编译有C++合成的项目不能用 setup.py 的方法,要手动编译:
假如我的pyrex 文件名是 test.pyx 像这样:

python pyrexc test.pyx (pyrexc文件在 C:\Python24\scripts 下面,要把这个目录在环境变量里设一下。或是复制到你用的目录里)

g++ -c test.c -mno-cygwin -mdll -IC:\Python24\include
g++ -mno-cygwin -shared -s test.o -LC:\Python24\libs -lpython24 -o test.pyd

就能通过编绎。


==== C++ ====
先编写一个C++文件:
{{{#!c
///////////////////////////////////////////////////////////////////
// in.h


class AAA{
      int num33;
      public:
             
             AAA(){
                  this->num33 = 10;
             }
             
             int getNum(){
                 return this->num33;
             }

             void setNum(int n222){
                 this->num33 = n222;
             }

};




// 这是创造类的函数
AAA* NewAAA(){
     return new AAA();
}

// 这是析构函数
void DelAAA(void *o){
     AAA* s = (AAA*)o;
     delete(s);
}

}}}

==== test.pyx ====
再编写test.pyx 文件将类包含进来

{{{#!python
# test.pyx
# 通过 cdef extern 把类在头部声名一次
# 因为C++ class 与 struct 有兼容性所以把类当成 struct 就搞定
cdef extern from "in.h":
  ctypedef struct AAA:
    int (* getNum)()
    void (* setNum)(int n222)
  AAA* NewAAA()
  void DelAAA(void *o)


cdef class PySomeClass:
  cdef AAA *thisptr

  def __new__(self):
    self.thisptr = NewAAA()

  def __dealloc__(self):
    DelAAA(self.thisptr)

  def getNum(self):
    return self.thisptr[0].getNum()
  
  def setNum(self,n):
    self.thisptr[0].setNum(n)

}}}

==== 运行 ====
{{{
import test
print test
print dir(test)
A = test.PySomeClass()
A.setNum(99777)
print A.getNum()
}}}
输出:
{{{
<module 'test' from 'D:\DTemp\PY__~1\test.pyd'>
['PySomeClass', '__builtins__', '__doc__', '__file__', '__name__']
99777
}}}

现在基本上就算是研制成功了。。


=== 主要原理 ===
    Pyrex最初的设计主要是用来也C语言合成使用的工具,也只支持定义一个 struct 的外部声名。
但在Pyrex声名extern的东西就会原封不运的转换成 C 代码。
C++ 的 class 与 struct 其实是一回事情,在C++编译器与C 混合编译的时侯就一起编译了。



{{{
欢迎Python 爱好者一起交流:
我的网名 ybeetle 电邮: [email protected]
}}}
 

          2006-08-17
= 反馈 =

Pyrex与C++混合编程 TableOfContents

综述

以前python想用C++混合编程只能通过 Boost 或 Swig 或是 DIY ,不过这三种方法都有些麻烦,不易控制与扩展。

其实高版本的Pyrex可以与C++混合编程,不过中文社区里好像没有介绍,这也是我写这篇教程的原因。

我的教程

附件:教程所用代码下载 attachment:pyxx.rar

准备的条件:

1. Python2.4安装
2. Pyrex安装必须是版本 Pyrex-0.9.4.1 才可以与C++编译
3. Dev-C++ 编译器 (版本最好是  4.9.9.2或以上)  Linux 下用 g++ 就行
4. 如果windows下必须要先修正 Python24.lib (在我的例程附件中带有修正后的 Python24.lib 文件) 
  • 修正PythonXX.lib 方法如下:

            1.拷贝python24.dll 到 C:\Python24\libs 目录下面
            2.在命令行模式下,转到Python 的lib 目录下面
            3.运行下面命令:
                    pexports python24.dll >python24.def
                    dlltool --dllname python24.dll --def python24.def --output-lib python24.lib
    
            Python24.dll 在 C:\WINNT\system32\python24.dll 下面。

上面的条件要先弄好才能开始玩,要不然别怪我教程不对。

说明

只是编译有C++合成的项目不能用 setup.py 的方法,要手动编译: 假如我的pyrex 文件名是 test.pyx 像这样:

python pyrexc test.pyx (pyrexc文件在 C:\Python24\scripts 下面,要把这个目录在环境变量里设一下。或是复制到你用的目录里)

g++ -c test.c -mno-cygwin -mdll -IC:\Python24\include g++ -mno-cygwin -shared -s test.o -LC:\Python24\libs -lpython24 -o test.pyd

就能通过编绎。

C++

先编写一个C++文件:

///////////////////////////////////////////////////////////////////
// in.h


class AAA{
      int num33;
      public:
             
             AAA(){
                  this->num33 = 10;
             }
             
             int getNum(){
                 return this->num33;    
             }

             void setNum(int n222){
                 this->num33 = n222; 
             }

};




// 这是创造类的函数
AAA* NewAAA(){
     return new AAA();
}

// 这是析构函数
void DelAAA(void *o){
     AAA* s = (AAA*)o;
     delete(s);
}

test.pyx

再编写test.pyx 文件将类包含进来

   1 # test.pyx
   2 # 通过 cdef extern 把类在头部声名一次
   3 # 因为C++ class 与 struct 有兼容性所以把类当成 struct 就搞定
   4 cdef extern from "in.h":
   5   ctypedef struct AAA:
   6     int (* getNum)()
   7     void (* setNum)(int n222)
   8   AAA* NewAAA()
   9   void DelAAA(void *o)
  10 
  11 
  12 cdef class PySomeClass:
  13   cdef AAA *thisptr
  14 
  15   def __new__(self):
  16     self.thisptr = NewAAA()
  17 
  18   def __dealloc__(self):
  19     DelAAA(self.thisptr)
  20 
  21   def getNum(self):
  22     return self.thisptr[0].getNum()
  23   
  24   def setNum(self,n):
  25     self.thisptr[0].setNum(n)

运行

import test
print test
print dir(test)
A = test.PySomeClass()
A.setNum(99777)
print A.getNum()

输出:

<module 'test' from 'D:\DTemp\PY__~1\test.pyd'>
['PySomeClass', '__builtins__', '__doc__', '__file__', '__name__']
99777

现在基本上就算是研制成功了。。

主要原理

  • Pyrex最初的设计主要是用来也C语言合成使用的工具,也只支持定义一个 struct 的外部声名。

但在Pyrex声名extern的东西就会原封不运的转换成 C 代码。 C++ 的 class 与 struct 其实是一回事情,在C++编译器与C 混合编译的时侯就一起编译了。

欢迎Python 爱好者一起交流:
我的网名 ybeetle 电邮: [email protected]
  • 2006-08-17

反馈

Pyrex (last edited 2009-12-25 07:10:31 by localhost)