gpt4 book ai didi

python - 如何将 C 中的 double 组转换为 python 列表?

转载 作者:太空宇宙 更新时间:2023-11-03 23:26:24 25 4
gpt4 key购买 nike

我的 C 代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double * Make_A(){
double A[2];
A[0]=0.00001;
double *p=(double *)&A;
return p;
}

还有我的python代码:

from ctypes import *
lib_cpp = cdll.LoadLibrary('./test.so')

C程序返回一个double数组指针,而我在python程序中得到了指针,我想将C数组转换为python列表或其他python结构,我该怎么办?

最佳答案

您可以使用 ctypes 完成您要求的操作,但是您的 C 代码存在一些缺陷。最大的问题是:

double A[2];

这会在堆栈 上创建一个包含 2 个 double 值的数组。当您使用 return p; 时,这实际上最终返回了一个指向堆栈上数组的指针。由于堆栈将在您的函数退出时展开,因此您不能再依赖指针的有效性。如果您想要一个包含 2 个 double 的数组,请使用 malloc 创建它们,然后返回指向该数组的指针。所以这段代码可以工作:

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

double * Make_A(){
/* Use Malloc to create an array of 2 doubles */
double *A = malloc(2 * sizeof(double));
A[0] = 0.00001;
A[1] = 42.0;
return A;
}

您还应该创建一个可以从 Python 调用的函数,以释放您在 C 端创建的任何指针:

/* Create a function that can free our pointers */
void freeptr(void *ptr)
{
free(ptr);
}

创建 C 代码后,我们可以使用 ctypes 加载共享对象并调用函数。

import ctypes
lib_cpp = ctypes.CDLL('./test.so')

# Make_A returns a pointer to two doubles
lib_cpp.Make_A.restype = ctypes.POINTER(ctypes.c_double * 2)

# freeptr takes one argument that is a void pointer
lib_cpp.freeptr.argtype = ctypes.c_void_p
# freeptr return void (no parameters)
lib_cpp.freeptr.restype = None

# Call Make_A and retrieve a double array pointer
darrayptr = lib_cpp.Make_A()
# Convert the array pointer contents to a Python list
floatlist = [x for x in darrayptr.contents]

# We need to free our pointer since Python won't know to
# do it for us. Similar to C where we must free anything we
# malloc.
lib_cpp.freeptr(darrayptr)

您可以在 Python documentation 中找到有关 ctypes 的资料;一些 sample code给你一些想法;还有这个tutorial .

如果您不想创建完整的 Python 模块,您还可以创建一个使用 Python 数据类型的共享对象,并返回一个包含 float 列表的 PyObject。关于 PyList 的信息可以在这个 documentation 中找到和 PyFloat 类型的文档可以在此 documentation 中找到:

PyObject* PyList_New(Py_ssize_t len)

Return value: New reference.

Return a new list of length len on success, or NULL on failure.

然后您可以将此示例添加到您的 C 代码之前所有其他包括:

#include <Python.h>

然后你可以添加这段代码:

PyObject* getList(void)
{
PyObject *dlist = PyList_New(2);
PyList_SetItem(dlist, 0, PyFloat_FromDouble(0.00001));
PyList_SetItem(dlist, 1, PyFloat_FromDouble(42.0));

return dlist;
}

在大多数安装了 python-dev(或 python-devel)包的 *nix 类型系统上,可以使用这样的命令构建共享对象:

gcc -c -Wall -Werror -fPIC `python-config --cflags` test.c
gcc -shared -o test.so test.o `python-config --ldflags`

现在在 Python 中你可以编写类似于我们之前的代码,但我们现在可以更直接地使用 Python 列表:

import ctypes
lib_cpp = ctypes.CDLL('./test.so')

# getList returns a PyObject
lib_cpp.getList.restype = ctypes.py_object

# Now call it and do something with the list
mylist = lib_cpp.getList()
print(mylist)

输出看起来像这样:

[1e-05, 42.0]

关于python - 如何将 C 中的 double 组转换为 python 列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26312711/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com