51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

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

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

  1. 基础类型变量 {#title-0} ====================
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
  1. 指针类型变量 {#title-1} ====================
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)
  1. Python 调用 C 函数 {#title-2} ============================

  2. 编写 C 函数

  3. 将 C 函数编译成自己平台的动态库(以 Mac 为例)

  4. 在 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 &lt;= 0 || ele_num &lt;= 0) { return; }

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

for (int i = 0; i &lt; 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)

赞(5)
未经允许不得转载:工具盒子 » C/C++ 编写 Python 扩展-调用C函数(1)