백엔드 개발 파이썬 튜토리얼 浅要分析Python程序与C程序的结合使用

浅要分析Python程序与C程序的结合使用

Jun 10, 2016 pm 03:16 PM
c python

Python 是一种用于快速开发软件的编程语言,它的语法比较简单,易于掌握,但存在执行速度慢的问题,并且在处理某些问题时存在不足,如对计算机硬件系统的访问,对媒体文件的访问等。而作为软件开发的传统编程语言 C 语言,却能在这些问题上很好地弥补 Python 语言的不足。因此,本文通过实例研究如何在 Python 程序中整合既有的 C 语言模块,包括用 C 语言编写的源程序和动态链接库等,从而充分发挥 Python 语言和 C 语言各自的优势。
概览

背景知识介绍
Python 语言的特点

Python 作为一门程序开发语言,被越来越多地运用到快速程序开发。Python 是一种解释型的,互动的,面向对象的编程语言,它包含了模块化的操作,异常处理,动态资料形态,以及类型的使用。它的语法表达优美易读,具有很多优秀的脚本语言的特点:解释的,面向对象的,内建的高级数据结构,支持模块和包,支持多种平台,可扩展。而且它还支持交互式方式运行,图形方式运行。它拥有众多的编程界面支持各种操作系统平台以及众多的各类函数库,利用 C 和 C++ 可以对它进行扩充。
C 语言的特点

C 语言作为最受人们欢迎的语言之一,有广泛的发展基础。简洁紧凑、灵活方便,功能强大是其特点。另外,C 语言是一门中级语言。它把高级语言的基本结构和语句与低级语言的实用性结合起来。由于可以直接访问物理地址,可以方便的对硬件进行操作。因此,很多的系统软件都是由 C 语言编写。
Python 语言与 C 语言的交互

为了节省软件开发成本,软件开发人员希望能够缩短的软件的开发时间,希望能够在短时间内开发出稳定的产品。Python 功能强大,简单易用,能够快速开发应用软件。但是由于 Python 自身执行速度的局限性,对性能要求比较高的模块需要使用效率更高的程序语言进行开发,例如 C 语言,系统的其他模块运用 Python 进行快速开发,最后将 C 语言开发的模块与 Python 开发的模块进行整合。在此背景下,基于 Python 语言与 C 语言的各自特点,用 C 语言来扩展现有的 Python 程序,显得很有意义。本文首先介绍几种常用的整合 Python 程序与 C 语言程序的方法,最后给出相应的实例。
利用 ctypes 模块整合 Python 程序和 C 程序
ctypes 模块

ctypes 是 Python 的一个标准模块,它包含在 Python2.3 及以上的版本里。ctypes 是一个 Python 的高级外部函数接口,它使得 Python 程序可以调用 C 语言编译的静态链接库和动态链接库。运用 ctypes 模块,能够在 Python 源程序中创建,访问和操作简单的或复杂的 C 语言数据类型。最为重要的是 ctypes 模块能够在多个平台上工作,包括 Windows,Windows CE,Mac OS X,Linux,Solaris,FreeBSD,OpenBSD。

接下来通过几个简单的例子来看一下 ctypes 模块如何整合 Python 程序和 C 程序。
源代码层面上的整合

利用 Python 本身提供的 ctypes 模块可以使 Python 语言和 C 语言在源代码层面上进行整合。本节介绍了如何通过使用 ctypes 库,在 Python 程序中可以定义类似 C 语言的变量。

下表列出了 ctypes 变量类型,C 语言变量类型和 Python 语言变量类型之间的关系:
表 1. ctypes,c 语言和 Python 语言变量类型关系

201547141954985.jpg (735×542)

表 1 中的第一列是在 ctypes 库中定义的变量类型,第二列是 C 语言定义的变量类型,第三列是 Python 语言在不使用 ctypes 时定义的变量类型。

举例:
清单 1. ctypes 简单使用

 >>> from ctypes import *        # 导入 ctypes 库中所有模块
 >>> i = c_int(45)            # 定义一个 int 型变量,值为 45 
 >>> i.value                # 打印变量的值
 45 
 >>> i.value = 56             # 改变该变量的值为 56 
 >>> i.value                # 打印变量的新值
 56

로그인 후 복사

从下面的例子可以更明显地看出 ctypes 里的变量类型和 C 语言变量类型的相似性:
清单 2. ctypes 使用 C 语言变量

 >>> p = create_string_buffer(10)   # 定义一个可变字符串变量,长度为 10 
 >>> p.raw                 # 初始值是全 0,即 C 语言中的字符串结束符' \0 '
'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
 >>> p.value = "Student"         # 字符串赋值
 >>> p.raw                 # 后三个字符仍是' \0 '
'Student\x00\x00\x00'
 >>> p.value = "Big"           # 再次赋值
 >>> p.raw                  # 只有前三个字符被修改,第四个字符被修改为' \0 '
'Big\x00ent\x00\x00\x00'

로그인 후 복사

下面例子说明了指针操作:
清单 3. ctypes 使用 C 语言指针

 >>> i = c_int(999)                 # 定义 int 类型变量 i,值为 999 
 >>> pi = pointer(i)                # 定义指针,指向变量 i 
 >>> pi.contents                   # 打印指针所指的内容
 c_long(999) 
 >>> pi.contents = c_long(1000)          # 通过指针改变变量 i 的值
 >>> pi.contents                   # 打印指针所指的内容
 c_long(1000)

로그인 후 복사

下面例子说明了结构和数组的操作:
清单 4. ctypes 使用 C 语言数组和结构体

 >>> class POINT(Structure):         # 定义一个结构,内含两个成员变量 x,y,均为 int 型
 ...   _fields_ = [("x", c_int), 
 ...         ("y", c_int)] 
 ... 
 >>> point = POINT(2,5)           # 定义一个 POINT 类型的变量,初始值为 x=2, y=5 
 >>> print point.x, point.y           # 打印变量
 2 5 
 >>> point = POINT(y=5)              # 重新定义一个 POINT 类型变量,x 取默认值
 >>> print point.x, point.y           # 打印变量
 0 5 
 >>> POINT_ARRAY = POINT * 3          # 定义 POINT_ARRAY 为 POINT 的数组类型
 # 定义一个 POINT 数组,内含三个 POINT 变量
 >>> pa = POINT_ARRAY(POINT(7, 7), POINT(8, 8), POINT(9, 9)) 
 >>> for p in pa: print p.x, p.y        # 打印 POINT 数组中每个成员的值
 ... 
 7 7 
 8 8 
 9 9

로그인 후 복사

Python 访问 C 语言 dll

通过 ctypes 模块,Python 程序可以访问 C 语言编译的 dll,本节通过一个简单的例子,Python 程序 helloworld.py 中调用 some.dll 中的 helloworld 函数,来介绍 Python 程序如何调用 windows 平台上的 dll。

导入动态链接库
清单 5. ctypes 导入 dll

 from ctypes import windll # 首先导入 ctypes 模块的 windll 子模块
 somelibc = windll.LoadLibrary(some.dll) # 使用 windll 模块的 LoadLibrary 导入动态链接库
로그인 후 복사

访问动态链接库中的函数
清单 6. ctypes 使用 dll 中的函数

somelibc. helloworld() # 这样就可以得到 some.dll 的 helloworld 的返回值。
로그인 후 복사

整个 helloworld.py 是这样的:
清单 7. Python hellpworld 代码

   from ctypes import windll 

   def callc(): 
   # load the some.dll 
   somelibc = windll.LoadLibrary(some.dll) 
   print somelibc. helloworld() 
   if __name__== “__main__”: 
   callc()

로그인 후 복사

在命令行运行 helloworld.py,在 console 上可以看到 some.dll 中 helloworld 的输出。
清单 8. Python hellpworld Windows command console 运行输出

   C:\>python C:\python\test\helloworld.py 
   Hello World! Just a simple test.

로그인 후 복사

Python 调用 C 语言 so

通过 ctypes 模块,Python 程序也可以访问 C 语言编译的 so 文件。与 Python 调用 C 的 dll 的方法基本相同,本节通过一个简单的例子,Python 程序 helloworld.py 中调用 some.so 中的 helloworld 函数,来介绍 Python 程序如何调用 linux 平台上的 so。

导入动态链接库
清单 9. ctypes 导入 so

 from ctypes import cdll   
   # 首先导入 ctypes 模块的 cdll 子模块,注意 linux 平台上使用 cdll 的,而不是 windll。
   somelibc = cdll.LoadLibrary(“./some.so”)
   # 使用 cdll 模块的 LoadLibrary 导入动态链接库
로그인 후 복사

访问动态链接库中的函数
清单 10. ctypes 使用 so 中的函数

   somelibc. helloworld() # 使用方法与 windows 平台上是一样的。

로그인 후 복사

整个 helloworld.py 是这样的:
清单 11. Python helloworld 代码

   from ctypes import cdll 

   def callc(): 
   # load the some.so 
   somelibc = cdll.LoadLibrary(some.so) 
   print somelibc. helloworld() 
   if __name__== “__main__”: 
   callc()

로그인 후 복사

在命令行运行 helloworld.py,在 linux 标准输出上可以看到 some.so 中 helloworld 的输出。
清单 12. Python hellpworld Linux shell 运行输出

   [root@linux-790t] python ./helloworld.py 
   Hello World! Just a simple test.

로그인 후 복사

Python 程序和 C 程序整合实例

以下我们举例用 Python 来实现一个小工具,用来实现 hash 算法,查看文件的校验和(MD5,CRC,SHA1 等等)。通过查看文件的校验和,可以知道文件在传输过程中是否被破坏或篡改。

Hash,一般翻译做“散列”,也有直接音译为"哈希"的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

由于相对 C 语言来说,Python 的运行效率较低,因此我们的 Python 小工具利用一个已有的 C 语言的动态链接库 (hashtcalc.dll) 来实现我们的程序。本例中,我们运用 wxPython 编写简单的 GUI 界面,通过 python 调用 hashtcalc.dll 的接口计算文件的校验和,然后输出在界面上。
架构图
图 1. 工具的架构图

201547142052510.gif (487×391)

hashcalc.dll 接口描述

函数名:calc_CRC32

函数:char* calc_CRC32(char *filename);

参数:文件名

返回值:字符串

说明:该函数对输入的文件内容进行计算,并且返回它的 CRC32

函数名:calc_MD5

函数:char* calc_MD5(char *filename);

参数:文件名

返回值:字符串

说明:该函数对输入的文件内容进行计算,并且返回它的 MD5

函数名:calc_SHA1

函数:char* calc_SHA1 (char *filename);

参数:文件名

返回值:字符串

说明:该函数对输入的文件内容进行计算,并且返回它的 SHA1
HashcalcAdapter 代码

HashcalcAdapter.py 实现了一个 python 的 class HashcalcAdapter,HashcalcAdapter 对 hashtcalc.dl 的 C 语言接口进行了封装,使得其他 python 模块可以直接通过 HashcalcAdapter 使用 hashtcalc.dll 中实现的 hash 算法。具体的代码如下:
清单 13. HashcalcAdapter.py 代码

 from ctypes import windll 
 from ctypes import * 

 class HashcalcAdapter(object): 
  def __init__(self, dllpath): 
    self._dllpath = dllpath 
    self._libc = windll.LoadLibrary(self._dllpath) 

  def calc_CRC32(self, filename): 
  new_filename = c_char_p(filename) 
  return self._libc.calc_CRC32(new_filename) 

  def calc_MD5(self, filename): 
  new_filename = c_char_p(filename) 
  return self._libc.calc_MD5(new_filename) 

  def calc_SHA1(self, filename): 
  new_filename = c_char_p(filename) 
  return self._libc.calc_SHA1(new_filename)

로그인 후 복사

运行界面
图 2. 工具的运行界面

201547142149896.jpg (553×415)

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

<gum> : Bubble Gum Simulator Infinity- 로얄 키를 얻고 사용하는 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
Nordhold : Fusion System, 설명
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
Mandragora : 마녀 트리의 속삭임 - Grappling Hook 잠금 해제 방법
3 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP와 Python : 다른 패러다임이 설명되었습니다 PHP와 Python : 다른 패러다임이 설명되었습니다 Apr 18, 2025 am 12:26 AM

PHP는 주로 절차 적 프로그래밍이지만 객체 지향 프로그래밍 (OOP)도 지원합니다. Python은 OOP, 기능 및 절차 프로그래밍을 포함한 다양한 패러다임을 지원합니다. PHP는 웹 개발에 적합하며 Python은 데이터 분석 및 기계 학습과 같은 다양한 응용 프로그램에 적합합니다.

PHP와 Python 중에서 선택 : 가이드 PHP와 Python 중에서 선택 : 가이드 Apr 18, 2025 am 12:24 AM

PHP는 웹 개발 및 빠른 프로토 타이핑에 적합하며 Python은 데이터 과학 및 기계 학습에 적합합니다. 1.PHP는 간단한 구문과 함께 동적 웹 개발에 사용되며 빠른 개발에 적합합니다. 2. Python은 간결한 구문을 가지고 있으며 여러 분야에 적합하며 강력한 라이브러리 생태계가 있습니다.

숭고한 코드 파이썬을 실행하는 방법 숭고한 코드 파이썬을 실행하는 방법 Apr 16, 2025 am 08:48 AM

Sublime 텍스트로 Python 코드를 실행하려면 먼저 Python 플러그인을 설치 한 다음 .py 파일을 작성하고 코드를 작성한 다음 CTRL B를 눌러 코드를 실행하면 콘솔에 출력이 표시됩니다.

PHP와 Python : 그들의 역사에 깊은 다이빙 PHP와 Python : 그들의 역사에 깊은 다이빙 Apr 18, 2025 am 12:25 AM

PHP는 1994 년에 시작되었으며 Rasmuslerdorf에 의해 개발되었습니다. 원래 웹 사이트 방문자를 추적하는 데 사용되었으며 점차 서버 측 스크립팅 언어로 진화했으며 웹 개발에 널리 사용되었습니다. Python은 1980 년대 후반 Guidovan Rossum에 의해 개발되었으며 1991 년에 처음 출시되었습니다. 코드 가독성과 단순성을 강조하며 과학 컴퓨팅, 데이터 분석 및 기타 분야에 적합합니다.

Python vs. JavaScript : 학습 곡선 및 사용 편의성 Python vs. JavaScript : 학습 곡선 및 사용 편의성 Apr 16, 2025 am 12:12 AM

Python은 부드러운 학습 곡선과 간결한 구문으로 초보자에게 더 적합합니다. JavaScript는 가파른 학습 곡선과 유연한 구문으로 프론트 엔드 개발에 적합합니다. 1. Python Syntax는 직관적이며 데이터 과학 및 백엔드 개발에 적합합니다. 2. JavaScript는 유연하며 프론트 엔드 및 서버 측 프로그래밍에서 널리 사용됩니다.

Golang vs. Python : 성능 및 확장 성 Golang vs. Python : 성능 및 확장 성 Apr 19, 2025 am 12:18 AM

Golang은 성능과 확장 성 측면에서 Python보다 낫습니다. 1) Golang의 컴파일 유형 특성과 효율적인 동시성 모델은 높은 동시성 시나리오에서 잘 수행합니다. 2) 해석 된 언어로서 파이썬은 천천히 실행되지만 Cython과 같은 도구를 통해 성능을 최적화 할 수 있습니다.

vscode에서 코드를 작성하는 위치 vscode에서 코드를 작성하는 위치 Apr 15, 2025 pm 09:54 PM

Visual Studio Code (VSCODE)에서 코드를 작성하는 것은 간단하고 사용하기 쉽습니다. vscode를 설치하고, 프로젝트를 만들고, 언어를 선택하고, 파일을 만들고, 코드를 작성하고, 저장하고 실행합니다. VSCODE의 장점에는 크로스 플랫폼, 무료 및 오픈 소스, 강력한 기능, 풍부한 확장 및 경량 및 빠른가 포함됩니다.

메모장으로 파이썬을 실행하는 방법 메모장으로 파이썬을 실행하는 방법 Apr 16, 2025 pm 07:33 PM

메모장에서 Python 코드를 실행하려면 Python 실행 파일 및 NPPEXEC 플러그인을 설치해야합니다. Python을 설치하고 경로를 추가 한 후 nppexec 플러그인의 명령 "Python"및 매개 변수 "{current_directory} {file_name}"을 구성하여 Notepad의 단축키 "F6"을 통해 Python 코드를 실행하십시오.

See all articles