Python 取消对c_void_p的整个数据的引用不仅仅是第一个字节
我有一个关于Pythons C类型和调用C函数的问题困扰了我几天。我正在使用Python3.5和ctypes包装一个C.dll 我有一个C函数接受一个Python 取消对c_void_p的整个数据的引用不仅仅是第一个字节,python,python-3.x,ctypes,dereference,Python,Python 3.x,Ctypes,Dereference,我有一个关于Pythons C类型和调用C函数的问题困扰了我几天。我正在使用Python3.5和ctypes包装一个C.dll 我有一个C函数接受一个void**作为输出参数。这应该包含一个指针,指向调用后图像的一些8位RGB数据 foo(void ** bar) 我声明Python参数和函数调用如下: >>bar = c_void_p() >>foo(byref(bar)) >>bar = POINTER(c_int)() >>foo(by
void**
作为输出参数。这应该包含一个指针,指向调用后图像的一些8位RGB数据
foo(void ** bar)
我声明Python参数和函数调用如下:
>>bar = c_void_p()
>>foo(byref(bar))
>>bar = POINTER(c_int)()
>>foo(byref(bar))
>>bar
<__main__.LP_c_int at 0x7fcf71d9d8c8> #so far so good?
>>bar.contents
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
并尝试接收数据:
>>data = c_byte(bar.value)
>>data.value
20
这实际上是第一个像素'R'-字节的合理值
但我没有设法达到任何字节超出这一点。为了便于理解,我现在得到c_void_p指向的第一个字节的值(?)
我还尝试:
>>data = (c_byte*3)(bar.value)
3仅用于测试目的(已尝试并达到数千次):
我还研究了我在网上找到的任何东西,包括:
,还有一些我现在找不到的
非常感谢您的帮助
编辑:
python文件的全部代码:
from ctypes import *
from ctypes_wrapper_dijsdk import *
init()
guids = find_cameras()
handle = c_void_p()
open_camera(guids, handle, 0)
start_acquisition(handle, 1)
imageHandle = c_void_p()
VOIDPP = POINTER(c_void_p)
imageData = VOIDPP(c_void_p())
get_image(handle, imageHandle, imageData)
byte_buf = cast(imageData.contents, POINTER(c_ubyte * (1920)))
for x in range(0, (1920)-1 ):
print("value: {:3d}".format(byte_buf.contents[x]))
dimension = (c_int*2)()
get_int_parameter(imageHandle, 0x20000103, dimension, 2)
value = c_void_p()
get_int_parameter(imageHandle, 0x20000200, value)
#from now on would be able to get the ImageData Size
print("ImageFormat = ", value.value, "see SDK.h")
release_image(imageHandle)
close_camera(handle)
exit()
从python调用C:
def get_image(handle, imageHandle, imageData, timeout = 0):
return d.SDK_GetImage(handle, byref(imageHandle), imageData, timeout)
其他信息:
- 实际上,代码中有更多的
输出参数,例如void**
。但它们不处理任何数组,似乎工作得很好。它们被声明为imageHandle
,并被称为c\u void\u p
byref()
- RGB数据存储为每行像素的字节流。所以它的维数[0]x维数[1]x位深度长
- 我不能提供任何C代码,因为它是共享库的一部分
- 这是做事的一种方式。此外,ctypes的官方文件:
dll.c:
#包括
#包括
#如果已定义(_WIN32)
#定义DLL\u导出\u declspec(dllexport)
#否则
#定义DLL_导出
#恩迪夫
#定义C_标记“来自C”
#定义PRINT_MSG_0()printf(“%s-[%s](%d)-[%s]\n”、C_标记、u文件、u行、u函数)
#定义PRINT\u ERR\u 1S(ARG0)printf(“%s:%s\n”,C\u标记,ARG0)
DLL\u导出整型测试(无效**pptr,大小\u t计数){
打印消息0();
如果(!pptr){
打印错误1(“收到空指针”);
返回-1;
}
如果(*pptr){
打印错误1(“接收到非空内部指针”);
返回-2;
}
无符号字符*buf=(无符号字符*)malloc(计数);
对于(大小i=0;i
code.py:
导入系统
输入数学
从ctypes导入c_ubyte、c_int、c_size、c_void、p、\
指针\
铸造
VoidPtrPtr=指针(c_void_p)
dll_dll=CDLL(“./dll.dll”)
test\u func=dll\u dll.test
test_func.argtypes=[VoidPtrPtr,c_size\t]
test_func.restype=c_int
dealloc\u func=dll\u dll.dealloc
dealloc_func.argtypes=[c\u void\u p]
显示\u值\u计数=5
FORMAT_STRING_PAT=“idx:{{:d}d}}-值:{{{:3d}”
定义获取打印索引(数组大小、值计数):
如果数组大小为1:
如果值\u count>2:
间隔大小=数组大小/(值计数-1)
对于范围内的idx(1,值\u计数-1):
收益率整数(四舍五入(idx*区间大小))
产量数组_大小-1
定义打印数组值(数组、数组大小、值计数=显示值计数):
index\u width=math.ceil(math.log10(数组大小))
格式字符串=格式字符串格式格式(索引宽度)
对于idx in获取打印索引(数组大小、值计数):
打印(format_string.format(idx,array.contents.contents[idx]))
def main():
尺寸=[
10,
100,
500,
1920 * 1080 * 3,
]
对于以大小为单位的大小:
UByteArr=c_ubyte*大小
UByteArrPtr=指针(UByteArr)
ubyteartrptr=指针(ubyteartrptr)
打印(“\n大小:{:d}”。格式(大小))
data=ubyteartrptr(ubyteartrptr())
打印(“data:{:},data.contents:{:}”。格式(data,data.contents))
#打印(addressof(数据),addressof(数据内容))
ptr=铸件(数据,PTRPTR)
res=测试功能(ptr,大小)
如果res<0:
打印(“{:s}返回{:d}。继续…\n”。格式(test\u func.\uu name\uuu,res))
持续
打印(“data:{:},data.contents:{:}”。格式(data,data.contents))
_打印数组值(数据、大小)
解除锁定功能(数据)
打印(“data:{:},data.contents:{:}”。格式(data,data.contents))
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{:s}on{:s}\n.”格式(sys.version,sys.platform))
main()
注释:
- 由于没有提到数组分配位置(C或Python),我选择了前一个选项(否则,双指针(
)就没有多大意义)。这增加了代码的复杂性(其中包括:void**
——以避免内存泄漏)。使用后一个选项将“生成”更少的代码,并且不需要dealloc
(我仍然想知道为什么需要它)void**
是一种泛型类型,没有太多信息。这就是为什么在C中,为了填充单个字节,我必须将其转换为void*
。同样的事情也适用于Python。我在Python中表达unsigned char*
的方式是通过void**
指针(c\u void\u p)
- 很多代码都是为了打印。这包括:
,仅用于选择数组中的5(\u get\u print\u index
)等距(从索引角度)元素显示值\u COUNT
-打印值\u打印\u数组\u值
(py35x64_test)e:\Work\Dev\StackOverflow\q051981858>“c:\Install\x86\Microsoft\visualstudio Community\2015\vc\vcvarsall.bat”x64
(py35x64_测试)e:\Work\Dev\StackOverflow\q051981858>dir/b
代码.py
dll.c
(py35x64_测试)e:\Work\Dev\StackOverflow\q051981858>cl/nologo dll.c/DDLL/link
def get_image(handle, imageHandle, imageData, timeout = 0):
return d.SDK_GetImage(handle, byref(imageHandle), imageData, timeout)
(py35x64_test) e:\Work\Dev\StackOverflow\q051981858>"c:\Install\x86\Microsoft\Visual Studio Community\2015\vc\vcvarsall.bat" x64
(py35x64_test) e:\Work\Dev\StackOverflow\q051981858>dir /b
code.py
dll.c
(py35x64_test) e:\Work\Dev\StackOverflow\q051981858>cl /nologo dll.c /DDLL /link /DLL /OUT:dll.dll
dll.c
Creating library dll.lib and object dll.exp
(py35x64_test) e:\Work\Dev\StackOverflow\q051981858>dir /b
code.py
dll.c
dll.dll
dll.exp
dll.lib
dll.obj
(py35x64_test) e:\Work\Dev\StackOverflow\q051981858>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py
Python 3.5.4 (v3.5.4:3f56838, Aug 8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32
Size: 10
data: <__main__.LP_LP_c_ubyte_Array_10 object at 0x000001F8189FBBC8>, data.contents: <__main__.LP_c_ubyte_Array_10 object at 0x000001F8189FBC48>
From C - [dll.c] (16) - [test]
data: <__main__.LP_LP_c_ubyte_Array_10 object at 0x000001F8189FBBC8>, data.contents: <__main__.LP_c_ubyte_Array_10 object at 0x000001F8189FBCC8>
idx: 0 - value: 1
idx: 2 - value: 3
idx: 5 - value: 6
idx: 8 - value: 9
idx: 9 - value: 10
From C - [dll.c] (35) - [dealloc]
data: <__main__.LP_LP_c_ubyte_Array_10 object at 0x000001F8189FBBC8>, data.contents: <__main__.LP_c_ubyte_Array_10 object at 0x000001F8189FBD48>
Size: 100
data: <__main__.LP_LP_c_ubyte_Array_100 object at 0x000001F8189FBCC8>, data.contents: <__main__.LP_c_ubyte_Array_100 object at 0x000001F8189FBDC8>
From C - [dll.c] (16) - [test]
data: <__main__.LP_LP_c_ubyte_Array_100 object at 0x000001F8189FBCC8>, data.contents: <__main__.LP_c_ubyte_Array_100 object at 0x000001F8189FBC48>
idx: 0 - value: 1
idx: 25 - value: 26
idx: 50 - value: 51
idx: 75 - value: 76
idx: 99 - value: 100
From C - [dll.c] (35) - [dealloc]
data: <__main__.LP_LP_c_ubyte_Array_100 object at 0x000001F8189FBCC8>, data.contents: <__main__.LP_c_ubyte_Array_100 object at 0x000001F8189FBE48>
Size: 500
data: <__main__.LP_LP_c_ubyte_Array_500 object at 0x000001F8189FBC48>, data.contents: <__main__.LP_c_ubyte_Array_500 object at 0x000001F8189FBEC8>
From C - [dll.c] (16) - [test]
data: <__main__.LP_LP_c_ubyte_Array_500 object at 0x000001F8189FBC48>, data.contents: <__main__.LP_c_ubyte_Array_500 object at 0x000001F8189FBDC8>
idx: 0 - value: 1
idx: 125 - value: 126
idx: 250 - value: 251
idx: 375 - value: 120
idx: 499 - value: 244
From C - [dll.c] (35) - [dealloc]
data: <__main__.LP_LP_c_ubyte_Array_500 object at 0x000001F8189FBC48>, data.contents: <__main__.LP_c_ubyte_Array_500 object at 0x000001F8189FBF48>
Size: 6220800
data: <__main__.LP_LP_c_ubyte_Array_6220800 object at 0x000001F8189FBDC8>, data.contents: <__main__.LP_c_ubyte_Array_6220800 object at 0x000001F818A62048>
From C - [dll.c] (16) - [test]
data: <__main__.LP_LP_c_ubyte_Array_6220800 object at 0x000001F8189FBDC8>, data.contents: <__main__.LP_c_ubyte_Array_6220800 object at 0x000001F8189FBEC8>
idx: 0 - value: 1
idx: 1555200 - value: 1
idx: 3110400 - value: 1
idx: 4665600 - value: 1
idx: 6220799 - value: 0
From C - [dll.c] (35) - [dealloc]
data: <__main__.LP_LP_c_ubyte_Array_6220800 object at 0x000001F8189FBDC8>, data.contents: <__main__.LP_c_ubyte_Array_6220800 object at 0x000001F8189FBEC8>