【问题标题】:Python ctypes: Passing an array of stringsPython ctypes:传递字符串数组
【发布时间】:2017-04-21 11:47:05
【问题描述】:

我在 Python 2.7 中有一个字符串数组,我想通过 ctypes 将其传递给 C 函数:

unsigned int SetParams(unsigned int count, const char **params)

所以我可以在python中定义参数:

import ctypes as ct
lib = ct.cdll.LoadLibrary('...')
lib.SetParams.restype  = ct.c_uint
lib.SetParams.argtypes = [ct.c_uint, ct.POINTER(ct.c_char_p)]

但是现在当我在 Python 函数中获得一组参数时,我想在上面的库调用中使用它,我该如何调用它呢?我在想这样的事情:

def setParameters(strParamList):
    numParams    = len(strParamList)
    strArrayType = ct.c_char_p * numParams
    strArray     = strArrayType()
    for i, param in enumerate(strParamList):
        strArray[i] = param
    lib.SetParams(numParams, strArray)

我刚从ctypes 开始,想知道是否有更自动化的方法可以做到这一点?分配strArray[i] = param 是否实际上正在重新分配?如果是这样,这似乎相当昂贵——有没有办法将字符串指针指向 Python 分配的缓冲区,或者它们不是以 NULL 结尾的?

更新我确实浏览了几个相关的问题,但找不到直接的问题来处理相同的问题。非常感谢

【问题讨论】:

  • 对于“更自动化”,您可能想看看 Cython。

标签: python c arrays string ctypes


【解决方案1】:

你的想法是正确的。该代码有效。调用,例如:

setParameters(['abc','def','ghi'])

我还没有查看源代码,但是 Python 2.7(32 位)上的 ctypes 确实通过了内部 Python 缓冲区(通过修改 C 函数中传递的字符串并在 Python 中调用后打印它进行测试) ,这就是为什么您应该只将上述 Python 字符串传递给采用 const char* 或至少已知不会修改字符串的函数的原因。由于 Python 字符串在 C 下是不可变的,因此对它们进行写入是禁止的。使用ctypes.create_string_buffer 创建一个可写字符串以传递给非常量char*

【讨论】:

    【解决方案2】:

    我需要对setParameters python函数中的for循环做如下调整

    for i, param in enumerate(strParamList):
       if isinstance(param, bytes):
          strArray[i] = c_char_p(param)
       else:
          strArray[i] = c_char_p(param.encode('utf-8'))
    

    如果setParameters 的数组参数是[b'abc', b'def']['abc','def'],则此方法有效。

    【讨论】:

      猜你喜欢
      • 2021-04-27
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-08
      • 2020-08-01
      相关资源
      最近更新 更多