首页 > 解决方案 > 在cython代码的测试中,使用ctypes是否有效?

问题描述

假设我得到了一些(经过彻底测试的)C 或 C++ 代码。假设我已经在 Cython 中实现了一些使用这个 C/C++ 代码的功能。Cython 功能基本上用作我的 C/C++ 代码的 Python 接口。

现在我想编写 Python 代码来测试我的 Cython 代码。使用 ctypes 访问 C/C++ 编译的共享对象并将其与相应 Cython 功能的结果进行比较是否有效?

我倾向于认为这个问题的答案是肯定的,这是一个有效的测试。我的犹豫是,在不了解 Cython 的内部结构的情况下,Cython 似乎有可能或有可能在幕后做我打算在这个测试中做的事情。

这是一些示例代码。C 头文件 some_c_code.h 是:

/* a is 1-dimensional array of size 5 */
void times_2(double* a);

而 C 实现文件 some_c_code.c 是:

void times_2(double* a) {
    for (int i = 0; i < 5; i++)
        a[i] *= 2;
}

Cython 文件是:

# distutils: sources = some_c_code.c

cimport numpy as np

cdef extern from "some_c_code.h":
    cdef void times_2(double*)

def py_times_2(a: np.ndarray):
    cdef double[:] b = a
    times_2(&b[0])

我们将 Cython 代码编译到文件 abc.cython-37m-linux.so 中。另外,我们还将 C 代码编译到另一个文件 libtestabc.so 中。

现在我建议py_times_2使用以下 Python 代码测试该函数:

import abc
from ctypes import cdll, c_double, POINTER
import numpy as np

def main():
    dll = cdll.LoadLibrary('libtestabc.so')
    dll_times_2 = dll.times_2
    dll_times_2.argtypes = POINTER(c_double)
    dll_times_2.restype = None

    a, a_dll = np.arange(5), np.arange(5)
    a_ctype = np.ctypeslib.as_ctypes(a_dll)

    abc.py_times_2(a)
    dll_times_2(a_ctype)

    assert np.allclose(a, a_dll)

if __name__ == '__main__':
    main()

这是对 Python 函数的有效测试py_times_2吗?

标签: c++ctestingcythonctypes

解决方案


推荐阅读