python - 如何使用 Ctypes 将此 numpy 数组传递给 C?
问题描述
目前我正在学习C类型。我的目标是在 python 中生成一个从 0 到 4*pi 的 numpy 数组 A,分 500 步。该数组被传递给计算这些值的正切的 C 代码。C 代码还将这些值传递回 python 中的 numpy 数组 B。
昨天我尝试简单地将一个值从 python 转换为 C 并且(在一些帮助之后)成功了。今天我尝试传递整个数组,而不是一个值。
我认为在 C 库中添加另一个函数来处理数组是个好主意。新函数应在循环中将 A 的每个值传递给函数 tan1() 并将该值存储在数组 B 中。
我有两个问题:
- 编写处理 numpy 数组 A 的函数
- 在 python 和 C 代码之间传递 numpy 数组。
我阅读了以下信息:
有帮助,但我仍然不知道如何解决我的问题。
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 端,数组总是衰减为指针。因此,您需要一个额外的参数来告诉您数组中的元素数量。
此外,如果您返回指向 Python 页面的 double 指针,则必须指定数组的大小。有了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)
推荐阅读
- azure-logic-apps - 如何在 Azure 逻辑应用程序中实现顺序护航
- c++ - 在套接字接收阻塞等待数据时保持窗口运动和关闭操作?
- r - 我们可以使用 R purrr 累积函数来汇总数据集吗?
- python - 如何手动或使用绘图插件(folium - Python)添加标记并能够导出或保存它?
- arrays - 如何在 Excel 中快速填充数据范围?
- amazon-web-services - AWS Amplify - CognitoIdentityCredentials 无权执行:sts:AssumeRole on resource
- react-native - React / Ionic:无效的钩子调用问题(使用历史记录进行重定向)
- c# - 如何使用 CsvHelper 从 ASP.NET MVC 中具有参数的方法生成 CSV
- reactjs - 有没有办法在 React 中只使用不同的子域调用 api?
- javascript - 动态类名样式