返回介绍

01. Python 工具

02. Python 基础

03. Numpy

04. Scipy

05. Python 进阶

06. Matplotlib

07. 使用其他语言进行扩展

08. 面向对象编程

09. Theano 基础

10. 有趣的第三方模块

11. 有用的工具

12. Pandas

ctypes

发布于 2022-09-03 20:46:14 字数 4886 浏览 0 评论 0 收藏 0

基本用法

ctypes 是一个方便 Python 调用本地已经编译好的外部库的模块。

In [1]:

from ctypes import util, CDLL

标准 C 库

使用 util 来找到标准 C 库:

In [2]:

libc_name = util.find_library('c')

# on WINDOWS
print libc_name
msvcr90.dll

使用 CDLL 来加载 C 库:

In [3]:

libc = CDLL(libc_name)

libc 包含 C 标准库中的函数:

In [4]:

libc.printf

Out[4]:

<_FuncPtr object at 0x0000000003CEE048>

调用这个函数:

In [5]:

libc.printf("%s, %d\n", "hello", 5)

Out[5]:

9

这里显示的 9printf 的返回值表示显示的字符串的长度(包括结尾的 '\0'),但是并没有显示结果,原因是 printf 函数默认是写在标准输出流上的,与 IPython 使用的输出流不一样,所以没有显示结果。

C 数学库

找到数学库:

In [6]:

libm_name = util.find_library('m')

print libm_name
msvcr90.dll

调用 atan2 函数:

In [7]:

libm = CDLL(libm_name)

libm.atan2(1.0, 2.0)
---------------------------------------------------------------------------
ArgumentError                             Traceback (most recent call last)
<ipython-input-7-e784e41ee9f3> in <module>()
 1 libm = CDLL(libm_name)
 2 
----> 3  libm.atan2(1.0, 2.0)

ArgumentError: argument 1: <type 'exceptions.TypeError'>: Don't know how to convert parameter 1

调用这个函数出错,原因是我们需要进行一些额外工作,告诉 Python 函数的参数和返回值是什么样的:

In [8]:

from ctypes import c_double

libm.atan2.argtypes = [c_double, c_double]
libm.atan2.restype = c_double

In [9]:

libm.atan2(1.0, 2.0)

Out[9]:

0.4636476090008061

Python 数学库中的结果一致:

In [10]:

from math import atan2

In [11]:

atan2(1.0, 2.0)

Out[11]:

0.4636476090008061

Numpy 和 ctypes

假设我们有这样的一个函数:

float _sum(float *vec, int len) {
    float sum = 0.0;
    int i;
    for (i = 0; i < len; i++) {
        sum += vec[i];
    }
    return sum
}

并且已经编译成动态链接库,那么我们可以这样调用:

from ctypes import c_float, CDLL, c_int
from numpy import array, float32
from numpy.ctypeslib import ndpointer

x = array([1,2,3,4], dtype=float32)

lib = CDLL(<path>)

ptr = ndpointer(float32, ndim=1, flags='C')
lib._sum.argtypes = [ptr, c_int]
lib._sum.restype = c_float

result = lib._sum(x, len(x))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文