简体   繁体   English

使用 python ctypes 将浮点缓冲区从共享库获取到 python 字符串

[英]Using python ctypes to get buffer of floats from shared library into python string

I'm trying to use python ctypes to use these two C functions from a shared library:我正在尝试使用 python ctypes 来使用共享库中的这两个 C 函数:

bool decompress_rgb(unsigned char *data, long dataLen, int scale)
float* getRgbBuffer()

The first function is working fine.第一个 function 工作正常。 I can tell by putting some debug code in the shared library and checking the input.我可以通过将一些调试代码放入共享库并检查输入来判断。

The problem is getting the data out.问题是把数据拿出来。 The RGB buffer is a pointer to a float (obviously) and this pointer stays constant during the life of the application. RGB 缓冲区是一个指向浮点数的指针(显然),并且该指针在应用程序的生命周期内保持不变。 Therefore whenever I want to decompress an image, I call decompress_rgb and then need to see what's at the location pointed to by getRgbBuffer .因此,每当我想解压缩图像时,我都会调用decompress_rgb然后需要查看getRgbBuffer指向的位置的内容。 I know that the buffer size is (720 * 288 * sizeof(float)) so I guess this has to come into play somewhere.我知道缓冲区大小是 (720 * 288 * sizeof(float)) 所以我想这必须在某个地方发挥作用。

There's no c_float_p type so I thought I'd try this:没有c_float_p类型所以我想我会试试这个:

getRgbBuffer.restype = c_char_p

Then I do:然后我做:

ptr = getRgbBuffer()
print "ptr is ", ptr

which just outputs:仅输出:

ptr = 3078746120

I'm guessing that's the actual address rather than the content, but even if I was successfully dereferencing the pointer and getting the contents, it would only be the first char.我猜这是实际地址而不是内容,但即使我成功取消引用指针并获取内容,它也只是第一个字符。

How can I get the contents of the entire buffer into a python string?如何将整个缓冲区的内容放入 python 字符串?

Edit: Had to change:编辑:不得不改变:

getRgbBuffer.restype = c_char_p

to

getRgbBuffer.restype = c_void_p

but then BastardSaint's answer worked.但后来 BastardSaint 的回答奏效了。

Not fully tested, but I think it's something along this line:没有完全测试,但我认为这是沿着这条线的东西:

buffer_size = 720 * 288 * ctypes.sizeof(ctypes.c_float)
rgb_buffer = ctypes.create_string_buffer(buffer_size) 
ctypes.memmove(rgb_buffer, getRgbBuffer(), buffer_size)

Key is the ctypes.memmove() function.关键是ctypes.memmove() function。 From the ctypes documentation :ctypes 文档

memmove(dst, src, count)
Same as the standard C memmove library function: copies count bytes from src to dst .与标准 C memmove 库 function 相同: count字节从src复制到dst dst and src must be integers or ctypes instances that can be converted to pointers. dstsrc必须是可以转换为指针的整数或 ctypes 实例。

After the above snippet is run, rgb_buffer.value will return the content up until the first '\0' .运行上述代码段后, rgb_buffer.value将返回内容直到第一个'\0' To get all bytes as a python string, you can slice the whole thing: buffer_contents = rgb_buffer[:] .要将所有字节作为 python 字符串,您可以对整个内容进行切片: buffer_contents = rgb_buffer[:]

It's been a while since I used ctypes and I don't have something which returns a "double *" handy enough to test this out, but if you want a c_float_p:自从我使用 ctypes 已经有一段时间了,我没有返回“双 *”的东西,足以方便地测试它,但如果你想要一个 c_float_p:

c_float_p = ctypes.POINTER(ctypes.c_float)

Reading BastardSaint's answer, you just want the raw data, but I wasn't sure if you're doing that as a workaround to not having a c_float_p.阅读 BastardSaint 的答案,您只需要原始数据,但我不确定您是否将其作为没有 c_float_p 的解决方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM