2009/03/20

C++和Python的相互调用

没有评论:
c++和python的互相调用


简单配置如下:

python安装目录: C:\Python26
头文件包含:
VStudio->Tools->Options->Directories->Include files 加入 C:\PYTHON26\INCLUDE
库文件包含:
VStudio->Tools->options->Directories->Library files 加入 C:\PYTHON26\LIBS

如果是debug版本,有可能会提示can't open file "python26_d.lib"没有调试版本的类库.
Solution: 把C:\Python26\libs\python26.lib复制一个python26_d.lib即可
否则直接用release版本就行; Or change python26_d.lib to python26.lib in "pyconfig.h" file, and comment "#define Py_DEBUG".


工程文件中包含了c++调用python中的函数,也同时把c++的函数做成了dll,以供python之调用;
所以也就发生另个一个问题,c++调用python时,最后关闭了python解释器
Py_Finalize(); 以至于python又调用dll时,发生错误;所以在生成dll时,注释掉
Py_Initialize();以及Py_Finalize();


若没有装VC,可以去微软网站下一个C++的编译器 VCTookitSetup.exe.
Under VC->VStudio Tools-> VStudio 2005 command prompt , 执行命令 cl cfile编译。


举例:

1、C中调用PYTHON
  #include
  int main(int argc, char *argv[])
  {
  Py_Initialize();
  PyRun_SimpleString("from time import time,ctime\n"
  "print 'Today is',ctime(time())\n");
  Py_Finalize();
  return 0;
  }
  直接用CL 文件名 编译就是

2、
PYTHON调用由C生成的DLL
  C代码:如FOO.C
  #include
  /* Define the method table. */
  static PyObject *foo_bar(PyObject *self, PyObject *args);
  static PyMethodDef FooMethods[] = {
  {"bar", foo_bar, METH_VARARGS},
  {NULL, NULL}
  };
  /* Here's the initialization function. We don't need to do anything
  for our own needs, but Python needs that method table. */
  void initfoo()
  {
  (void) Py_InitModule("foo", FooMethods);
  }
  /* Finally, let's do something ... involved ... as an example function. */
  static PyObject *foo_bar(PyObject *self, PyObject *args)
  {
  char *string;
  int len;
  if (!PyArg_ParseTuple(args, "s", &string))
  return NULL;
  len = strlen(string);
  return Py_BuildValue("i", len);
  }
  C定义文件:foo.def
  EXPORTS
  initfoo
  编译生成foo.dll
  cl -c foo.c;
  link foo.obj /dll /def:foo.def /OUT:foo.dll
将foo.dll 改名为 foo.pyd
  在PYTHON中调用:
  import foo
  dir(foo)
  …
  即可以看到结果:
  >>> import foo
  >>> dir(foo)
  ['__doc__', '__file__', '__name__', 'bar']
  >>> ^Z
为简化python使用C的数据类型,可以 import ctypes . it is better over pyrex .


3 C调用由python生成的dll
写一个C程序,该程序存放调用python的函数接口。然后将该C程序和python程序一起做成DLL即可。


主要参考

C++ 扩展和嵌入 Python
http://www.vckbase.com/document/viewdoc/?id=1540

Anjuta: C++ IDE for Ubuntu

没有评论:
Linux下C/C++工具推荐Anjuta

vi/vim, gedit 和emacs is simple

KDeveloper is based on KDE

Eclipse, 基于Java的IDE, 慢,耗内存

NetBeans , 基于Java

基于GTK/Glade的Anjuta集成开发环境(IDE)不错,体积小,速度快,有自动代码补全和提示功能. I feel even for python IDE, anjuta can beat eric-python!

1. Install anjuta directly by menu->Applications->add/remove->programming

2. 安装C/C++开发文档
在编程的过程中有时会记不得某个函数的用法,通常这时查man手册是比较快的,所以把这个manpages-dev软件包安装上。想要看某个函数的用法就man它。
执行安装命令: sudo apt-get install manpages-dev

manpage的索引由mandb命令管理,有时在安装了新的manpage文件后,可能需要更新一下索引才能看到man -k 和man -f这些函数。
执行命令:mandb -c

然后,就可以查看这些文档了。比如,fopen的:
man fopen

3. 写个Hello World 的C++程序
在Anjuta中新建Project。出现“应用程序向导”,点“前进”;工程类型选“C++”中的“Generic C++”,之后点“前进”;“前进”;工程选项(Project Options)中,全选“否”,再点“前进”,应用即可。点左侧“工程”按钮,点工程名“foobar-cpp”,双击“main.cc”打开它,可以看到,main() 函数已预先写好了。按下“Shift+F11”编译,再按“F3”运行(这两个快捷键对应菜单在“Build”菜单下。),Anjuta的更多功能等待发掘,点击“设置”》“Plugins”...

References:
[1] http://anjuta.org/apt
[2] http://forum.ubuntu.org.cn/viewtopic.php?t=79137

2009/03/08

ctypes, pyrex and Boost

没有评论:
ctypes 是为方便python程序调用C dll程序的接口而规范数据类型。
-ctypes是一个Python模块,
-可在Python中创建和操作C语言的数据类型
-可在动态链接库中传递参数到C的函数中去

Pyrex 是将Python脚本转化为可编译的C代码,以便高效执行和被C程序调用。
- 它有多出的语法(除与python兼容外)
- 它需要 pyrexc test.pyx 生成 C代码 test.c
- 然后编译成 test.so 或 test.dll

Boost_python是方便写python程序调用C dll.


相对来说 ctypes使用较方便! 使用pyrex,如果需要在Python代码访问C代码的Struct和Union,比较麻烦。

cytpes tutorial

Pyrex - a Language for Writing Python Extension Modules

pyrex一例
1,先生成简单的
//test.h
int tadd(int a, int b);

//test.c
#include "test.h"
int tadd(int a, int b) { return a+b; };

gcc -c test.c #生成test.o
ar -rsv libtest.a test.o #生成了 libtest.a 静态库

2 测试lib是否可用
// ttest.c
#include
#include "test.h"
void main(int argc, void * argv[])
{ int c=1; c = tadd(1, 4); printf("c = %d \r\n", c); }

gcc ttest.c -ltest -L. #生成了a.out
./a.out #结果是: c = 5

证明我们的lib库是可以正常工作的


3,写一个python的模块td.pyx,调用它libtest里的tadd()函数
#td.pyx
cdef extern from "test.h":
int tadd(int i, int j)

def tdadd(int i, int j):
cdef int c
c=tadd(i, j) #在这行调用c=tadd(i, j)
return c

编译:
pyrexc td.pyx #生成 td.c
gcc -c -fPIC -I/usr/include/python2.4/ td.c #生成td.o
gcc -shared td.o -ltest -L. -o td.so #生成了td.so。这个就是python可以用的模块so

安装 pyrex,略。
测试:
import td
dir(td)
['__builtins__', '__doc__', '__file__', '__name__', 'tdadd']
td.tdadd(1,2)
3

OK。

2009/02/13

Ubuntu 8.10下如何升级eric4-python到4.3.0

没有评论:
Ubuntu下的python IDE 软件:
gedit虽然已经很好了,可还是想要一个集成开发环境。ubuntu下的
Eric python IDE 似乎还行。
Stani's Python Editor: another choice 还行,但不能 create project.
PyPE : not good
vim 但没有集成环境
sudo apt-get install vim-full vim-python
最终选用 Eric Python Editor
升级ubuntu from 8.04 to 8.10后,发现eric-python 不再能 auto python code completion (出现提示窗口,但不能选择!)。

解决方案: 重新安装eric4-4.3.0

0. uninstall previous eric4.1.0 from synaptic

1. download eric4 package from http://eric-ide.python-projects.org/eric4-download.html

2. sudo apt-get install python-qt4-dev python-qscintilla2

3. cd to eric-package directory
sudo python install.py
若提示:
Please enter the name of the Qt data directory.
(That is the one containing the 'qsci' subdirectory.)
>>
输入 /usr/share/qt4

4. 运行.
目前ubuntu source 未包含最新eric版本,因此在terminal 执行eric4 (位于/usr/local/bin/eric4)

Note: 目前eric4.3在laptop上窗口显示有问题。

2009/02/06

安装Ubuntu 8.10 带来的问题

没有评论:
Ubuntu 8.10: firefox中flash无声音
解决: sudo apt-get install flashplugin-nonfree-extrasound

启动我的python程序,多了如下两个bugs. :-(

/usr/lib/python2.5/site-packages/pytz/__init__.py:29: UserWarning: Module _mysql was already imported from /var/lib/python-support/python2.5/_mysql.so, but /var/lib/python-support/python2.5 is being added to sys.path
from pkg_resources import resource_stream

import MySQLdb
import matplotlib
会出现 UserWarning, 但顺序
import matplotlib
import MySQLdb
则不会

解释: matplotlib may import mySQLdb and a warning message is issued if mySQLdb already is imported.
而 /usr/lib/python2.5/site-packages/pytz has to do with timezones. python-tz ( pytz: python time zone)

解决方法:
1。 简易。 调整 import 顺序.
2. or look into
/usr/lib/python2.5/site-packages/pytz/__init__.py:29
找到 pkg_resources.py, 修改该文件。
/usr/lib/python2.5/site-packages/pkg_resources.py, Line 2272:

From:
if fn and normalize_path(fn).startswith(loc):
To:
if fn and (fn.startswith(loc) or normalize_path(fn).startswith(loc)):

the warning goes away.




/usr/lib/python2.5/site-packages/pytz/__init__.py:29: UserWarning: Module dateutil was already imported from /var/lib/python-support/python2.5/dateutil/__init__.py, but /var/lib/python-support/python2.5 is being added to sys.path
from pkg_resources import resource_stream

这个好像与 旧的pyc文件没有 update有关,It may be caused by outdated *.pyc files. Can try (sudo python -c 'import dateutil') - that should regenerate
outdated *.pyc files. 第二个warning消失.


/usr/lib/python2.5/site-packages/CGAL/__init__.py:3: RuntimeWarning: Python C API version mismatch for module Kernel: This Python has API version 1013, module Kernel has version 1012.
from Kernel import *
/usr/lib/python2.5/site-packages/CGAL/__init__.py:4: RuntimeWarning: Python C API version mismatch for module Triangulations_2: This Python has API version 1013, module Triangulations_2 has version 1012.
from Triangulations_2 import *
/usr/lib/python2.5/site-packages/CGAL/__init__.py:5: RuntimeWarning: Python C API version mismatch for module Triangulations_3: This Python has API version 1013, module Triangulations_3 has version 1012.
from Triangulations_3 import *

这个与 CGAL 版本落后有关, 按 cgal-python version = 0.9.3 ,python=2.5 重新自己编译. OK. (参见 cgal-python安装)


当然 Ubuntu 8.10也带来一个pylab/matplotlib的好处: pylab绘图完成后会将控制权返回,因此可以在一个canvas上interactive plotting. 以前必须关闭canvas返回。