ctypes 中的 const void* 指针

问题描述 投票:0回答:2

如果我有一个可写的

buffer
,我可以使用
ctypes.c_void_p.from_buffer
函数来获取指向该缓冲区的C指针。

但是如何处理不可写的缓冲区呢?如何形成一个

const
指针,将其传递给需要
const void*
的 C 代码,而不需要制作不可写缓冲区的可写副本?

我考虑过

c_void_p.from_address
,但缓冲区(和内存视图)似乎没有公开它们的地址。


一些澄清:

>>> import ctypes
>>> b = buffer("some data that supports the buffer interface, like a str")
>>> ptr = ctypes.c_void_p.from_buffer(b)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: buffer is read-only
>>> ptr = ctypes.c_void_p.from_buffer_copy(b)    # works, but has to copy data
>>> ptr = ctypes.CONST(c_void_p).from_buffer(b)  # (I'm making this one up)
>>> ptr = ctypes.c_void_p.from_address(???)      # could work; how to get addr?

这可以与

void some_api(const void* read_only_data)
一起使用,例如:

>>> ctypes.cdll.LoadLibrary(some_lib).some_api(ptr)

带有

from_buffer_copy
的方法可以工作,但需要先复制缓冲区。我正在寻找解决缓冲区可写要求的方法,因为没有人会在那里写入,并且我想避免数据的冗余复制。

python python-2.7 buffer constants ctypes
2个回答
0
投票

您可以使用 ctypes 将 Python 字符串转换为

char*
,它指向存储 Python 字符串数据的实际内存。

随意双重投射。


0
投票

对于

void*
,可以直接将
str/unicode
(Python 2.x) 或
bytes/str
(Python 3.x) 传递给函数。 它们将被编组为指向值字节的指针,或者在 Unicode 字符串的情况下,编组为指向字符串的适合操作系统的 UTF 编码字节的指针,例如Windows 上的 UTF-16LE。

示例(Python 3.x):

import ctypes as ct

crt = ct.CDLL('msvcrt')

# void* memcpy(void* dest, const void* src, size_t count);
memcpy = crt.memcpy
memcpy.argtypes = ct.c_void_p, ct.c_void_p, ct.c_size_t
memcpy.restype = ct.c_void_p

dest = ct.create_string_buffer(10)  # writeable buffer
src = bytes([1,2,3,4,5])  # immutable bytes
print(dest.raw.hex(' '))
memcpy(dest, src, len(src))
print(dest.raw.hex(' '))
src = '马克😉'  # immutable str (will marshal as UTF-16LE bytes on Windows)
memcpy(dest, src, len(src.encode('utf-16le')))
print(dest.raw.hex(' '))
print(dest.raw.decode('utf-16le'))

输出:

00 00 00 00 00 00 00 00 00 00
01 02 03 04 05 00 00 00 00 00
6c 9a 4b 51 3d d8 09 de 00 00
马克😉
© www.soinside.com 2019 - 2024. All rights reserved.