C/C++ 编写 Python 扩展-调用C函数(1)

在 Python 中使用 ctypes 模块可以很轻松定义 C 类型的变量,以及调用 C/C++ 函数.

1. 基础类型变量

from ctypes import *


def test():

    a = c_short(10)
    b = c_int(20)
    c = c_long(30)
    d = c_longlong(40)
    e = c_float(3.14)
    f = c_double(3.14)
    g = c_longdouble(3.14)

    print(a, a.value)
    print(b, b.value)
    print(c, c.value)
    print(d, d.value)
    print(e, e.value)
    print(f, f.value)


if __name__ == '__main__':
    test()

程序输出结果:

c_short(10) 10
c_int(20) 20
c_long(30) 30
c_long(40) 40
c_float(3.140000104904175) 3.140000104904175
c_double(3.14) 3.14

2. 指针类型变量

from ctypes import *


def test():

    a = c_int(20)
    # 定义 int 类型指针
    b = POINTER(c_int)
    # 指针指向 a 变量
    b = pointer(a)

    # 打印指针的值
    print(b)
    # 访问指针指向的空间的值
    print(b.contents)


if __name__ == '__main__':
    test()

程序输出结果:

<__main__.LP_c_int object at 0x7fb6f826c9c0>
c_int(20)

3. Python 调用 C 函数

  1. 编写 C 函数
  2. 将 C 函数编译成自己平台的动态库(以 Mac 为例)
  3. 在 Python 中使用 ctypes 模块调用 C 函数

我们的 C 函数在 test.c 文件,代码如下:

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

void memory_copy(const void* src, void* dst, size_t ele_size, size_t ele_num)
{
    if (NULL == src)
    {
        return;
    }

    if (NULL == dst)
    {
        return;
    }

    if (ele_size <= 0 || ele_num <= 0)
    {
        return;
    }

    char* new_dst = (char *)dst;
    const char* new_src = (const char *)src;

    for (int i = 0; i < ele_size * ele_num; ++i)
    {
        *new_dst++ = *new_src++;
    }
}

使用下面的命令将其打成 Mac 平台的动态库文件:

gcc -dynamiclib -o libmy.dylib test.c

接下来,在 Python 中调用 C 函数代码如下:

from ctypes import *


# 加载动态库
c_obj = CDLL('libmy.dylib')

# 由于函数进行的逐字节拷贝, 需要将字符串定为字节类型
src = b'hello world'
# 开辟空间字符串长度大小的空间
dst = create_string_buffer(len(src) + 1)

# 打印空间的数据
print('dst:', dst.raw)
# 打印空间的内容
print('dst:', dst.value)

# 调用自定义的C函数实现内存拷贝
c_obj.memory_copy(src, pointer(dst), 1, len(src) + 1)

print('dst:', dst.raw)
print('dst:', dst.value)

未经允许不得转载:一亩三分地 » C/C++ 编写 Python 扩展-调用C函数(1)