效率提升二十倍:Python和C的混合编程

文章目录

    • 先写一个希尔排序
    • 调用
    • ctypes中的数据类型

ctypes是python标准库的一员,相当于为python与C语言之间假设了一道桥梁,使得二者之间的混合编程成为可能。本文就演示一下,在Python中通过ctypes模块对C语言的dll文件进行调用的过程。

先写一个希尔排序

例如我们用C语言写一个希尔排序

//sort.h
#include 
void ShellSort(double *arr, int n);
//sort.c
#include "sort.h"

void ShellSort(double *arr, int n){
	double temp;
	int j;
	for(int nSub=n/2; nSub>0; nSub/=2)
		for(int i=nSub; i<n; i++){
			temp = arr[i];
			for(j=i-nSub;  j>=0 && temp<arr[j]; j-=nSub)
				arr[j+nSub] = arr[j];
			arr[j+nSub] = temp;
		}
}

先写一个test.c做测试。

//test.c
#include "sort.h"
int main(){
	double arr[5] = {1,3,5,4,2};
	ShellSort(arr,5);
	for(int i=0; i<5; i++)
		printf("%lf ", arr[i]);
	return 0;
}

首先通过gcc -shared -osort.c变成sort.dll,再将sort.dll链接到test.c中,从而生成test.exe。gcc会自动将-l后面的sort识别为sort.dll

>gcc -shared -o sort.dll sort.c
>gcc -o test.exe .\test.c -L./ -lsort
>test.exe
1.000000 2.000000 3.000000 4.000000 5.000000

test.exe成功运行,说明我们这个函数是正确的。

调用

接下来需要在python中通过ctypes进行调用。务必注意python和dll须有相同的数据位数。在windows下,如果用mingw中的gcc,只能编译32位程序,而若Python为64位,则会报出如下错误

>>> import ctypes
>>> dll = ctypes.CDLL("./sort.dll")
Traceback (most recent call last):
  File "", line 1, in <module>
  File "C:\Python310\lib\ctypes\__init__.py", line 374, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 不是有效的 Win32 应用程序。

为了解决这个问题,需要下载安装mingw-w64。

在正确安装并设置mingw-w64之后,进入python

>>> import ctypes
>>> dll = ctypes.CDLL("./sort.dll")
>>> tenValues = ctypes.c_double * 10    #新建一个长度位10的double型数组
>>> v = tenValues(1,3,5,7,9,8,6,4,2,10)
>>> dll.ShellSort(v,10)
0
>>> for i in v:print(i,end=' ')
...
1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0

可见希尔排序的确起到了作用。

ctypes中的数据类型

ctypes c数据类型
c_bool _Bool
c_byte,c_int8 char
c_short, c_int16 short
c_int, c_int32 int
c_long long
c_longlong, c_int64 long long
c_char, c_char_p char, char*
c_double, c_float double, float
c_longdouble long double
c_size_t size_t
c_ssize_t ssize_t
c_ubyte, c_uint8 unsigned char
c_ushort, c_uint16 unsigned short
c_uint, c_uint32 unsigned int
c_ulong unsigned long
c_ulonglong, c_uint64 unsigned long long
c_void_p void *
c_wchar wchar_t *
c_wchar_p wchar_p *

你可能感兴趣的:(#,Python标准库,python,c语言,windows)