在Python中使用C程序
很早就知道Python中可以方便的调用C程序,但一直没有尝试过。今天来试一试。环境ubuntu14.04LTS,Python2.7.6,gcc4.8.4。
首先准备在Python中要用到的C程序:
#include<stdio.h>
#include<math.h>
#define True 1
#define Flase 0
#define None -1
int isprime(unsigned long long n)
//*判断一个正整数是否是质数,
//若是质数,返回True,其他,返回Flase
{
unsigned long long i=0;
unsigned long long sqn;
short flag=None;
if(n<2)
{
flag=Flase;
}
else if(n==2)
{
flag=True;
}
else if(n%2==0)
{
flag=Flase;
}
else
{
i=1;
sqn = (unsigned long long)sqrt(n);
do{
i = i+2;
if( i > sqn ){
flag=True;
}
if( n%i == 0 ){
flag=Flase;
}
}while(flag==None);
}
return flag;
}
把它保存成isprime.c,然后将它编译可被Python调用的成动态链接库,在ubuntu中可以用gcc这样编译:
gcc isprime.c -fPIC -shared -o isprime.so
其中各参数的含义是:
-fPIC
作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),产生的代码中,没有绝对地址,全部使用相对地址,故而代码被加载器加载到内存的任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。
-shared
生成一个共享的目标文件,它能够与其他的目标一起链接生成一个可执行的文件。
-o isprime.so
输出文件名为isprime.so。.so(shared object)是Linux下的动态连接共享库文件,与Windows中的.dll对应。
然后运行如下代码调用isprime.so:
from ctypes import *
import os
isprime = cdll.LoadLibrary(os.getcwd() + '/isprime.so')
print isprime.isprime(23)
注意os.getcwd() + ‘/isprime.so’是isprime.so文件路径,此处使用了os.getcwd()获取当前路径。按这样的写法,Python程序应与isprime.so在同一目录下。这样,就成功的在Python中使用了C程序。
Ctypes是python的外部功能库,允许调用DLL或共享库中的函数,并用纯Python封装这些库。从python2.5开始Ctypes成为了标准的模块之一。Ctypes还具有兼容C的数据类型,下表列出了Ctypes变量类型,C语言变量类型和Python语言变量类型之间的关系:
Ctypes type | C type | Python type |
---|---|---|
c_char | char | 1-character string |
c_wchar | wchar_t | 1-character unicode string |
c_byte | char | int/long |
c_ubyte | unsigned char | int/long |
c_short | short | int/long |
c_ushort | unsigned short | int/long |
c_int | int | int/long |
c_uint | unsigned int | int/long |
c_long | long | int/long |
c_ulong | unsigned long | int/long |
c_longlong | __int64 or long long | int/long |
c_ulonglong | unsigned __int64 or unsigned long long | int/long |
c_float | float | float |
c_double | double | float |
c_char_p | char * (NUL terminated) | string or None |
c_wchar_p | wchar_t * (NUL terminated) | unicode or None |
c_void_p | void * | int/long or None |
简单的使用示例如下:
from ctypes import *
i = c_int(45)
print i.value
这样,就可以直接在Python中声明C变量类型,调用C程序了。
更多高级用法参见 “浅谈 Python 程序和 C 程序的整合” 。