python調用C函數


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語言數據類型對應關系

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM