python 與 c可以相互調用,在做后台服務時底層服務用C/C++編寫,通過python調用C庫可以極大的提高開發效率。
下面對幾種調用方式舉例說明
1 python通過指針傳遞浮點型數組給C函數
bird = cdll.LoadLibrary("./bird.so") aList=[1.0, 1.1, 1.2, 1.3, 1.4, 1.5] arrayMy = (c_float*len(aList)) a = arrayMy() for i in range(0, len(a)): a[i] = aList[i] count = c_int(len(a)) bird.ptr_test(a, count)
這里注意調用C函數時傳入的數組類型定義方法與初始值設定,ctypes模塊定義了與C語言數據類型對應的python類型,調用C函數時要確保傳入類型一致。
2 python通過指針傳遞字符串數組給C函數
info='Hello , glade to meet you!' pInfo = create_string_buffer(info, len(info)) bird.buf_in_test(info, sizeof(pInfo))
注意create_string_buffer的作用是把python中的字符串類型轉換為一個指針指向的字符串數組。
3 python接收C函數返回的字符串以及長度
bufLen = 100 c_pBuf = create_string_buffer('', bufLen) c_bufLen = c_int(bufLen) bird.buf_out_test(c_pBuf, byref(c_bufLen)) print c_bufLen.value print string_at(c_pBuf)
注意byref是通過指針地址傳入參數
4 C函數里分配內存傳給python使用
ptr_char = pointer(c_char()) retlen = c_int(0) bird.malloc_test(byref(ptr_char), byref(retlen)) print string_at(ptr_char) print retlen.value
bird.free_test(ptr_char)
注意python里定義一個字符指針的方法ptr_char = pointer(c_char()),定義一個整型變量的方法retlen = c_int(0) , byref(ptr_char)取指針的地址傳入函數。
5 測試的python與C源碼
#!/usr/bin/python from ctypes import * bird = cdll.LoadLibrary("./bird.so") aList=[1.0, 1.1, 1.2, 1.3, 1.4, 1.5] arrayMy = (c_float*len(aList)) a = arrayMy() for i in range(0, len(a)): a[i] = aList[i] count = c_int(len(a)) bird.ptr_test(a, count) info='Hello , glade to meet you!' pInfo = create_string_buffer(info, len(info)) bird.buf_in_test(info, sizeof(pInfo)) bufLen = 100 c_pBuf = create_string_buffer('', bufLen) c_bufLen = c_int(bufLen) bird.buf_out_test(c_pBuf, byref(c_bufLen)) print c_bufLen.value print string_at(c_pBuf) ptr_char = pointer(c_char()) retlen = c_int(0) bird.malloc_test(byref(ptr_char), byref(retlen)) print string_at(ptr_char) print retlen.value bird.free_test(ptr_char)
#include <stdio.h> #include <string.h> #include <stdlib.h> int ptr_test(float * ptr, int count) { if(ptr){ int i = 0; printf("\n"); for (i = 0; i < count; ++i){ printf("%f | ", ptr[i]); } printf("\n"); } return 0; } int buf_in_test(char*buf, int len) { if(buf){ int i = 0; printf("\n"); for (i = 0; i < len; ++i){ printf("%c", buf[i]); } printf("\n"); } return 0; } int buf_out_test(char*buf, int *len) { if(buf){ char *test_str = "hello world!"; memcpy(buf, test_str, strlen(test_str)); *len = strlen(test_str); } return 0; } int malloc_test(char **pBuf, int *len) { *pBuf = (char*)malloc(100); printf("malloc add:%p\n", *pBuf); *len = 100; memcpy(*pBuf, "hello", 5); return 0; } int free_test(char *pBuf) { if (pBuf){ printf("free add:%p\n", pBuf); free(pBuf); } return 0; }
6 ctypes里定義的數據類型與C語言數據類型對應關系