17.2 非常簡單的途徑:Jython 和 IronPython
一個簡單的java類
public class JythonTest{
public void greeting(){
System.out.println("Hello,world"):
}
}
java編譯器編譯,例如javac
$javac JythonTest.java
如果使用java工作,那麼可以使用jythonc命令把Python類編譯成Java類,這樣的Java類能直接導入到Java程序中。
已經編譯了這個類之後,就自動啓動Jython:
$CLASSPATH=JythonTest.class jython
之後直接導入這個類:
>>>import JythonTest
>>>test = JythonTest()
>>>test.greeting()
Hello,world!
17.3.1 SWIG
SWIG是簡單包裝和接口生成器的縮寫。
1.它是做什麼的
使用SWIG的過程是簡單的,首先要確保一些C語言代碼
1.爲代碼寫接口文件,這很像C語言的頭文件
2.爲了自動的產生C語言代碼要在接口文件上運行SWIG
3.把原來的C語言代碼和產生的包裝代碼一起編譯來產生共享庫。
2.更喜歡Pi
迴文是忽略掉空格和標點後,正着讀反着讀都一樣的句子。
一個簡單的用來檢測迴文的C語言函數(palindrome.c)
#include <string.h>
int is_palindrome(char *text) {
int i,n=strlen(text):
for (i=0;i<=n/2;++i) {
if (text[i] != text[n-i-1]) return 0;
}
return 1;
}
python版本的檢測迴文的函數
def is_palindrome(text):
n = len(text)
for i in range(len(text)//2):
if text[i] != text[n-i-1]:
return False
return True
3.接口文件
把接口描述放到palindrome.i中。
如果定義了頭文件palindrome.h,SWIG就可以從頭文件中得到需要的信息。因此如果擁有一個頭文件,可以隨意使用它。顯示地編寫一個接口文件的理由之一是知道SWIG是怎麼包裝代碼的。最終要的是排除一些東西,比如,如果要包裝一個巨大的C語言庫,可能需要導出一些函數到Python中,在這種情況下,只要把需要導出的函數放到接口文件中就可以了。
在接口文件中,就像在一個頭文件中做得那樣,只需聲明要導出的所有的函數即可,除此之外,頭部的一個單元內,可以指定包含的頭文件以及在這之前的一個%module聲明,即爲模塊定義的一個名字。
迴文庫的接口
%module palindrome
%{
#include <string.h>
%}
extern int is_palindrome(char *text):
4.運行SWIG
$swig -python palindrome.i
之後會得到兩個新文件-----palindrome_wrap.c palindrome.py
5.編譯、連接以及使用
$gcc -c palindrome.c
$gcc -I$PYTHON_HOME -I$PYTHON_HOME/Include -c palinrome_wrap.c
$gcc -shared palindrome.o palindrome_wrap.o -o _palindrome.so
可能需要的所有文件在 比如/usr/include/python2.6
$gcc -c palindrome.c
$gcc -I/usr/include/python2.6 -c palindrome_wrap.c
$gcc -shared palindrome.o palindrome_wrap.o -o _palindrome.so
在運行了這些不可思議後,會得到一個很有用的文件_palindrome.so。這就是共享庫它能直接導入python
>>>import _palindrome
>>>dir(_palindrome)
['__doc__','__file__','__name__','is_palindrome']
>>>_palindrome.is_palindrome('ipreferpi')
1
>>>_palindrome.is_palindrome('notlob')
0
6.一條通過編譯器的魔法森林的捷徑
使用Distutils 可以優雅的避免那些配置。Distutils直接支持SWIG。
引用計數
使用兩個宏Py_INCREF和Py_DECREF分別增加和減少一個對象的引用計數。