Python ctypes: 传递 'const char ** ' 参数给函数

1 投票
2 回答
6082 浏览
提问于 2025-04-16 12:27

我想把一个包含字符串的Python列表传递给一个C语言的函数,而这个函数需要的是const char **类型的参数。我在这里看到过相关的问题和解决方案,但对我来说似乎不管用。下面是我的示例代码:

argList = ['abc','def']
options = (ctypes.c_char_p * len(argList))()
options[:] = argList

运行后出现了以下错误:

Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
TypeError: string or integer address expected instead of str instance

我哪里做错了呢?


补充说明:

大家似乎都认为这段代码应该能正常工作。下面是如何重现这个问题。

在我的Python命令行中输入的以下四行代码展示了我的问题。

Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> argList = ['abc', 'def']
>>> options = (c_char_p * len(argList))()
>>> options[:] = argList
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: string or integer address expected instead of str instance
>>>

2 个回答

3

还有一种语法可以考虑:

>>> from ctypes import *
>>> a = 'abc def ghi'.split()
>>> b=(c_char_p * len(a))(*a)
>>> b[0]
'abc'
>>> b[1]
'def'
>>> b[2]
'ghi'

在我的2.7.1和3.1.3版本上都能正常工作。如果数组是字节类型(bytes),而不是字符串类型(str),在3.2版本上也能正常工作:

Python 3.2 (r32:88445, Feb 20 2011, 21:29:02) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from ctypes import *
>>> a = b'abc def ghi'.split()
>>> b=(c_char_p * len(a))(*a)
>>> b[0]
b'abc'
>>> b[1]
b'def'
>>> b[2]
b'ghi'

看起来在3.2之前的版本允许从字符串(Unicode)转换为字节。这可能不是个错误,因为3.X系列的版本试图消除字节和字符串之间的自动转换(明确的比隐含的更好)。

1

这个示例的Python代码是正确的。

你能把完整的代码贴出来吗?

在这种情况下,我猜测你的字符串里面包含了嵌入的NUL字节,这可能导致了这个类型错误(TypeError)异常。

希望这个链接对你有帮助:http://docs.python.org/c-api/arg.html

撰写回答