Python ctypes 的数组输出?
array output from Python ctypes?
我需要从 Python 调用一个 C 函数,使用 ctypes 并让该函数提供一个或多个返回给 Python 的数组。数组将始终是简单类型,如 long、bool、double。
如果数组可以动态调整大小,我会非常喜欢。我会在每次调用前知道需要的,但不同的调用应该使用不同的尺寸。
我想我应该在 Python 中分配数组并让 C 代码覆盖内容,这样 Python 最终可以取消分配它分配的内存。
我同时控制 Python 和 C 代码。
我现在有这个不起作用:
C:
FOO_API long Foo(long* batch, long bufferSize)
{
for (size_t i = 0; i < bufferSize; i++)
{
batch[i] = i;
}
return 0;
}
Python:
print "start test"
FooFunction = Bar.LoadedDll.Foo
longPtrType = ctypes.POINTER(ctypes.c_long)
FooFunction.argtypes = [longPtrType, ctypes.c_long]
FooFunction.restype = ctypes.c_long
arrayType = ctypes.c_long * 7
pyArray = [1] * 7
print pyArray
errorCode = FooFunction(arrayType(*pyArray), 7)
print pyArray
print "test finished"
产生:
start test
[1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1]
test finished
应该生产:
start test
[1, 1, 1, 1, 1, 1, 1]
[0, 1, 2, 3, 4, 5, 6]
test finished
为什么这不起作用?还是我需要以不同的方式执行此操作?
C数组使用python列表构建;两者都是不同的对象。代码是打印 python 列表,它不受 Foo
调用的影响。
您需要构建C数组,传递它,然后在调用后使用它:
arrayType = ctypes.c_long * 7
array = arrayType(*[1] * 7)
print list(array)
errorCode = FooFunction(array, len(array))
print list(array)
感谢 faltru 的快速回答。我没有立即注意到它,与此同时我到达了这个,这似乎也有效。我想知道一个是否比另一个更可取?
print "start test"
FooFunction = GpGlobals.LoadedDll.Foo
longArrayType = ctypes.c_long * (7)
FooFunction.argtypes = [longArrayType, ctypes.c_long]
FooFunction.restype = ctypes.c_long
pyArray = longArrayType()
for l in pyArray:
print l
errorCode = FooFunction(pyArray, 7)
for l in pyArray:
print l
print "test finished"
我最初并不认为这适用于动态大小的数组,但我所要做的就是在每次调用之前重新定义 argtypes。
我需要从 Python 调用一个 C 函数,使用 ctypes 并让该函数提供一个或多个返回给 Python 的数组。数组将始终是简单类型,如 long、bool、double。
如果数组可以动态调整大小,我会非常喜欢。我会在每次调用前知道需要的,但不同的调用应该使用不同的尺寸。
我想我应该在 Python 中分配数组并让 C 代码覆盖内容,这样 Python 最终可以取消分配它分配的内存。
我同时控制 Python 和 C 代码。
我现在有这个不起作用:
C:
FOO_API long Foo(long* batch, long bufferSize)
{
for (size_t i = 0; i < bufferSize; i++)
{
batch[i] = i;
}
return 0;
}
Python:
print "start test"
FooFunction = Bar.LoadedDll.Foo
longPtrType = ctypes.POINTER(ctypes.c_long)
FooFunction.argtypes = [longPtrType, ctypes.c_long]
FooFunction.restype = ctypes.c_long
arrayType = ctypes.c_long * 7
pyArray = [1] * 7
print pyArray
errorCode = FooFunction(arrayType(*pyArray), 7)
print pyArray
print "test finished"
产生:
start test
[1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 1, 1, 1, 1]
test finished
应该生产:
start test
[1, 1, 1, 1, 1, 1, 1]
[0, 1, 2, 3, 4, 5, 6]
test finished
为什么这不起作用?还是我需要以不同的方式执行此操作?
C数组使用python列表构建;两者都是不同的对象。代码是打印 python 列表,它不受 Foo
调用的影响。
您需要构建C数组,传递它,然后在调用后使用它:
arrayType = ctypes.c_long * 7
array = arrayType(*[1] * 7)
print list(array)
errorCode = FooFunction(array, len(array))
print list(array)
感谢 faltru 的快速回答。我没有立即注意到它,与此同时我到达了这个,这似乎也有效。我想知道一个是否比另一个更可取?
print "start test"
FooFunction = GpGlobals.LoadedDll.Foo
longArrayType = ctypes.c_long * (7)
FooFunction.argtypes = [longArrayType, ctypes.c_long]
FooFunction.restype = ctypes.c_long
pyArray = longArrayType()
for l in pyArray:
print l
errorCode = FooFunction(pyArray, 7)
for l in pyArray:
print l
print "test finished"
我最初并不认为这适用于动态大小的数组,但我所要做的就是在每次调用之前重新定义 argtypes。