PythoncTypes传递数据指针
我正在访问API,无法获取返回的数据。两个浮点指针将指向一个数据数组。我必须假设API工作正常。另一个函数调用为我检索的数据的长度提供了一个参数。尝试时,此值低于PythoncTypes传递数据指针,python,pointers,ctypes,Python,Pointers,Ctypes,我正在访问API,无法获取返回的数据。两个浮点指针将指向一个数据数组。我必须假设API工作正常。另一个函数调用为我检索的数据的长度提供了一个参数。尝试时,此值低于长度 函数的C头 int function(int, float * data1, float * data2) ctypes设置 dll.function.argtypes = (c_int, POINTER(c_float), POINTER(c_float)) dll.function.restypes
长度
函数的C头
int function(int, float * data1, float * data2)
ctypes设置
dll.function.argtypes = (c_int, POINTER(c_float), POINTER(c_float))
dll.function.restypes = c_int
尝试1失败:
x = c_float()
y = c_float()
status = dll.function(1, byref(x), byref(y))
程序崩溃或访问冲突写入
尝试2失败:
x = POINTER(c_float)()
y = POINTER(c_float)()
status = dll.function(1, x, y)
空指针错误
尝试3失败:
dll.function.argtypes = (c_int, c_void_p, c_void_p)
x = c_void_p()
y = c_void_p()
status = dll.function(1, x, y)
空指针错误
尝试4失败:
array = c_float * length
x = array()
y = array()
status = dll.function(1, byref(x), byref(y))
程序崩溃
尝试5失败:
array = c_float * length
x = POINTER(array)()
y = POINTER(array)()
status = dll.function(1, x, y)
空指针错误或ArgumentError:应为LP_c_float实例,而不是LP_c_float_数组[length]
尝试6失败:
x = (c_float*length)()
y = (c_float*length)()
a = cast(x, POINTER(c_float))
b = cast(y, POINTER(c_float))
status = dll.function(1, a, b)
程序崩溃
我错过了什么?为什么
我相信这些类型是正确的。我正试图适当地满足他们,但仍然存在一些问题。我是否需要以某种方式“malloc”内存?(我确定我需要在获得数据后释放)
这是在使用Python 2.7 32位的Windows 7上实现的
我已经研究了其他类似的问题,并没有找到解决办法。我想知道,在这一点上,我是否可以将这个问题归咎于API。这真的取决于您对这些浮点指针所做的操作
如果你试图穿越它,即
for(int i = 0; i < size; i++)
printf("%f\n%, data1[i])
for(int i=0;i
当然,这是有问题的,因为没有分配数组。您只需传递一个指向浮点的指针。仅此而已
您需要首先分配内存。为此,尝试4看起来更有希望,但我怀疑您的C函数中存在导致崩溃的问题
很难说没有看到该函数的实现。中介绍了如何处理指针和数组
我为你准备了一个虚拟的例子
main00.c:
#如果已定义(_WIN32)
#定义DECLSPEC\u DLLEXPORT\u DECLSPEC(DLLEXPORT)
#否则
#定义DECLSPEC\u DLLEXPORT
#恩迪夫
静态int kSize=5;
DECLSPEC_DLLEXPORT int size(){
返回kSize;
}
DECLSPEC_DLLEXPORT int函数(int-dummy、float*data1、float*data2){
对于(int i=0;i
代码00.py:
!/usr/bin/env python
导入系统
将ctypes导入为ct
c_float_p=ct.POINTER(ct.c_float)
def主(*argv):
dll=ct.CDLL(“./dll00.so”)
size=dll.size
size.argtypes=[]
size.restype=ct.c_int
function=dll.function
function.argtypes=[ct.c_int,c_float_p,c_float_p]
function.restype=ct.c_int
sz=大小()
印刷品(深圳)
数据1=(ct.c_float*sz)()
数据2=(ct.c_float*sz)()
res=函数(1,ct.cast(数据1,c_float_p),ct.cast(数据2,c_float_p))
对于范围内的i(sz):
打印(数据1[i],数据2[i])
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{0:s}{1:d}位在{2:s}\n.format(“.join(sys.version.split(“\n”)中的项的item.strip()),如果sys.maxsize>0x100000000,则为64,否则为32,sys.platform))
rc=main(*sys.argv[1:]
打印(“\n完成”)
系统出口(rc)
注释:
- C部分试图模仿.dll的功能(或者至少是我所理解的功能):
- size-获取数组大小
- 函数-填充数组(直到其大小-假设调用者正确分配了数组)
- Python部分很简单:
- 加载.dll
- 为这两个函数定义argtypes和restype(在代码中是restype's)(对于size\u func不需要)
- 了解长度
- 初始化数组
- 使用ctypes.cast将它们传递给函数_func
输出(在Lnx上,因为构建C代码要简单得多,但在Win上也能工作):
建议使用cffi而不是ctypes。cffi更方便。不久前我也在使用ctypes,但人们建议切换。他们是对的,我再也不会使用ctypes了。:)关于如何使用指针的示例可以在两个char*
中找到,长度相同?它们在函数中分配或者它们应该由调用方(Python)分配?这两个float*都是指向数组的指针。它们需要由调用方分配。这回答了你的问题吗?刚刚接受。我花了一周的时间去做其他事情。谢谢。
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> gcc -shared -o dll00.so main00.c
[cfati@cfati-ubtu16x64-0:~/Work/Dev/StackOverflow/q050043861]> python3 code00.py
Python 3.8.5 (default, Jan 27 2021, 15:41:15) [GCC 9.3.0] 64bit on linux
5
0.0 -1.0
1.0 -2.0
2.0 -3.0
3.0 -4.0
4.0 -5.0