目录

一、向C函数传入 int,且C函数返回 int

二、向C函数传入 string,且C函数返回 int

三、向C函数传入 string,且C函数返回 string


一、向C函数传入 int,且C函数返回 int

1.1)C代码(返回两个整数之和)

int int_plus(int a, int b)
{
    return a + b;
}

编译C函数库:

gcc -g -Wall -I. -shared -Wall -lc plus.c -o plus.so

1.2)Python 代码

# -*- coding: utf-8 -*-

import ctypes

dll = ctypes.CDLL('plus.so') # 加载C函数库

def int_plus():
    for i in range(5):
        s = dll.int_plus(i + 1, i ** 2) # 调用C函数,传入整数,返回整数
        print("({0} + 1) + {0} ** 2 = {1}".format(i, s))

def call_so():
    int_plus()

if "__main__" == __name__:
    call_so()

Python 代码执行结果:

python call-plus.py 
(0 + 1) + 0 ** 2 = 1
(1 + 1) + 1 ** 2 = 3
(2 + 1) + 2 ** 2 = 7
(3 + 1) + 3 ** 2 = 13
(4 + 1) + 4 ** 2 = 21

二、向C函数传入 string,且C函数返回 int

1.1)C代码(拼接两个字符串)

#include <stdio.h>
#include <string.h>

// 返回0 : 成功
// 返回1 : 失败
int str_plus(char *s, int len, char *a, char *b)
{
    int l = strlen(a) + strlen(b);
    if(l >= len)
    {
        return -1;
    }
    if(NULL == s)
    {
        return -1;
    }
    snprintf(s, len, "%s%s", a, b);

    return 0;
}

编译C代码:

gcc -g -Wall -I. -shared -Wall -lc plus.c -o plus.so

2.2)Python 代码

# -*- coding: utf-8 -*-

import ctypes
import random

dll = ctypes.CDLL('plus.so')

def str_plus():
    basestr = "abcdefghijklmnopqrstuvwxyz0123456789"
    BASESTR = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    for i in range(5):
        alen = random.randint(5, 10) # 随机生成一个字符串
        a = basestr[:alen]

        blen = random.randint(5, 10) # 随机生成另一个字符串
        b = BASESTR[:blen]
        #print('b', b)

        rlen = random.randint(9, 20) # 申请一个随机长度的字符串,用来存储 a 和 b 两个字符串的拼接结果
        s = ctypes.create_string_buffer(rlen)
        ret = dll.str_plus(s, rlen, a.encode(), b.encode()) # 调用C语言中的拼接函数
        if ret != 0:
            print(i, "str_plus faild")
        else:
            print(i, s.value.decode())

def call_so():
    str_plus()

if "__main__" == __name__:
    call_so()

Python 代码执行结果:

$ python call-plus.py
0 str_plus faild
1 abcdefgABCDEFGH
2 abcdefABCDEFGHIJ
3 str_plus faild
4 str_plus faild

三、向C函数传入 string,且C函数返回 string

3.1)C函数代码(生成一个指定长度的字符串)

#include <strings.h>

// 生成一个随机字符串,最后一个字符是 '\0'
char * str_random(char *p, int size)
{
    if(NULL == p)
    {
        return NULL;
    }
    bzero(p, size);
    for(int i = 0; i < size; i++)
    {
        p[i] = 'a' + (i % ('z' - 'a' + 1));
    }
    p[size - 1] = '\0';

    return p;
}

编译C代码

gcc -g -Wall -I. -shared -Wall -lc plus.c -o plus.so

3.2)Python 代码

# -*- coding: utf-8 -*-

import ctypes
import random

dll = ctypes.CDLL('plus.so')

def str_random():
    dll.str_random.restype = ctypes.c_char_p

    for i in range(5):
        slen = random.randint(5, 10)
        s = ctypes.create_string_buffer(slen)
        x = dll.str_random(s, slen)
        print(x.decode()) # 返回的字符串是 binary 形式,需要进行 decode()

def call_so():
    str_random()

if "__main__" == __name__:
    call_so()

Python 代码执行结果:

$ python call-plus.py
abcde
abcdefghi
abcdefghij
abcdef
abcdefghij

python库调用方法 python库函数调用_字符串