如何使用 Ctypes 将这个 numpy 数组传递给 C?

2024-01-04

目前我正在学习 C 类型。我的目标是生成一个 numpy python 中的数组 A 从 0 到 4*pi,需要 500 步。该数组被传递给 计算这些值的正切的 C 代码。 C代码也 将这些值传递回 python 中的 numpy 数组 B。

昨天我尝试简单地将一个值从 python 转换为 C 并 (经过一些帮助)成功了。今天我尝试传递整个数组,而不是一个 价值。

我认为向 C 库添加另一个函数是个好主意 处理数组。新函数应该在循环中传递每个值 A 的值传递给函数 tan1() 并将该值存储在数组 B 中。

我有两个问题:

  • 编写处理 numpy 数组 A 的函数
  • 在 python 和 C 代码之间传递 numpy 数组。

我阅读了以下信息:

  • https://nenadmarkus.com/p/numpy-to-native/ https://nenadmarkus.com/p/numpy-to-native/
  • 如何将 NumPy 数组与 ctypes 一起使用? https://stackoverflow.com/questions/3195660/how-to-use-numpy-array-with-ctypes

有帮助,但我仍然不知道如何解决我的问题。

C 代码(仅看起来相关的部分):

double tan1(f) double f;
{
    return sin1(f)/cos1(f); 
}


void loop(double A, int n);
{
    double *B;
    B = (double*) malloc(n * sizeof(double));
    for(i=0; i<= n, i++)
    {
        B[i] = tan1(A[i])
    }
}

Python代码:

import numpy as np
import ctypes


A = np.array(np.linspace(0,4*np.pi,500), dtype=np.float64)

testlib = ctypes.CDLL('./testlib.so')
testlib.loop.argtypes = ctypes.c_double,
testlib.loop.restype = ctypes.c_double


#print(testlib.tan1(3))
    

我知道 ctypes.c_double 在这种情况下是错误的,但这就是我在 1 值版本中所拥有的,并且还不知道要替换什么。

我能否获得一些关于如何实现这一目标的反馈?


您需要返回动态分配的内存,例如将您的 C 代码更改为:

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

double tan1(double f) {
    return sin(f)/cos(f);
}

double *loop(double *arr, int n) {
    double *b = malloc(n * sizeof(double));
    for(int i = 0; i < n; i++) {
        b[i] = tan(arr[i]);
    }
    return b;
}

void freeArray(double *b) {
    free(b);
}

在 Python 方面,您必须声明参数和返回类型。正如其他人在评论中提到的,您还应该释放动态分配的内存。请注意,在 C 方面,数组总是衰减为指针。因此,您需要一个附加参数来告诉您数组中元素的数量。

另外,如果将 double 指针返回到 Python 页面,则必须指定数组的大小。和np.frombuffer您可以使用数据而无需复制数据。

import numpy as np
from ctypes import *

testlib = ctypes.CDLL('./testlib.so')

n = 500
dtype = np.float64
input_array = np.array(np.linspace(0, 4 * np.pi, n), dtype=dtype)
input_ptr = input_array.ctypes.data_as(POINTER(c_double))

testlib.loop.argtypes = (POINTER(c_double), c_int)
testlib.loop.restype = POINTER(c_double * n)
testlib.freeArray.argtypes = POINTER(c_double * n),

result_ptr = testlib.loop(input_ptr, n)
result_array = np.frombuffer(result_ptr.contents)

# ...do some processing
for value in result_array:
    print(value)

# free buffer
testlib.freeArray(result_ptr)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Ctypes 将这个 numpy 数组传递给 C? 的相关文章

随机推荐