在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 程序的整合” 。

发表评论

电子邮件地址不会被公开。 必填项已用*标注