【问题标题】:How to pass a string buffer from python function to C Api via ctype如何通过ctype将字符串缓冲区从python函数传递到C Api
【发布时间】:2020-12-08 08:35:04
【问题描述】:

我有一个带有以下原型的 C api 函数,我希望通过 ctypes 模块从 Python 2.6/2.7 调用它。

C 函数:

int function_name( char *outputbuffer, int outputBufferSize, 
                   const char *input, const char *somestring2 );

这里的 outputbuffer 是一种字符串缓冲区,一旦根据 input 和 somestring2 调用此函数,就会在其中插入一个字符串作为输出。

我们如何在 python 中创建这个缓冲区(输出缓冲区)以及这个函数的 argtype 是什么

【问题讨论】:

  • 我不是 Python 专家,但请查看 ctypescreate_string_buffer
  • 为什么要加c++标签?该问题清楚地表明感兴趣的主题是“C api函数”。
  • @pqans 对造成的任何不便深表歉意。我猜 c++ 标签在推荐中,所以被无意中添加了。将其删除。

标签: python c ctypes


【解决方案1】:

首先,您导入 ctypes 模块。然后,您需要加载包含上述函数的 c dll。之后,您需要设置该函数的参数类型和结果类型。最后,您创建目标缓冲区并调用您的函数。

Python:

import ctypes as ct

MAX_BUFSIZE = 100
  
mycdll = ct.CDLL("path_to_your_c_dll")  # for windows you use ct.WinDLL(path)

mycdll.function_name.argtypes = [ct.c_char_p, ct.c_int,
                                 ct.c_char_p, ct.c_char_p]

mycdll.function_name.restype = ct.c_int

mystrbuf = ct.create_string_buffer(MAX_BUFSIZE)
result = mycdll.function_name(mystrbuf, len(mystrbuf), 
                              b"my_input", b"my_second_input")

使用 strncpy 的工作示例:

import ctypes as ct

MAX_BUFSIZE = 100

mycdll = ct.CDLL("libc.so.6")  # on windows you use cdll.msvcrt, instead

mycdll.strncpy.argtypes = [ct.c_char_p, ct.c_char_p, ct.c_size_t]

mycdll.strncpy.restype = ct.c_char_p

mystrbuf = ct.create_string_buffer(MAX_BUFSIZE)
dest = mycdll.strncpy(mystrbuf, b"my_input", len(mystrbuf))

print(mystrbuf.value)

Python 3 输出:

user@Mint20:~/Dokumente/Programmieren/sites/Stackoverflow$ python3 --version
Python 3.8.5

user@Mint20:~/Dokumente/Programmieren/sites/Stackoverflow$ python3 python_ctypes.py 
b'my_input'

Python 2 输出:

user@Mint20:~/Dokumente/Programmieren/sites/Stackoverflow$ python2 --version
Python 2.7.18

user@Mint20:~/Dokumente/Programmieren/sites/Stackoverflow$ python2 python_ctypes.py 
my_input

【讨论】:

  • 感谢您的回答。我没有在 mystrbuf 中存储/返回输出。另外,我尝试像您建议的 b"my_input" 和 ct.c_char_p("my_input") 那样以两种方式发送输入。但是 mystrbuf 仍然是空的。有什么想法吗?
  • 如果您分别在 linux 或 windows 上工作,请加载 libc.so.6msvcrt,而不是加载您的 c 代码。将 function_name 替换为 strncpy 并提供正确的 arg- 和 restypes。然后你会发现它有效!你的 c 代码看起来怎么样?
  • 我刚刚添加了一个带有建议的 strncpy 的工作示例
  • 还有一件事忘了补充,我正在研究 python 2。python 2 和 3 的 ctypes 有什么重大变化吗?
  • docs.python.org/2.7/library/ctypes.html,但我不知道这个早期版本的功能集。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-21
  • 2015-01-22
  • 1970-01-01
  • 2012-01-15
  • 2020-05-20
  • 2015-10-29
相关资源
最近更新 更多