gpt4 book ai didi

python - 使用 ctypes 将字符串从 Python 传递到 C 共享库的问题

转载 作者:太空狗 更新时间:2023-10-30 01:32:51 41 4
gpt4 key购买 nike

我在通过 ctypes 将字符串从 Python 传递到 C 时遇到困难:

我的C代码(编译成hello.so)

...
typedef struct test{
unsigned int a;
unsigned char* b;
} my_struct;

int hello(my_struct *in) {
FILE *fp;
...
fprintf(fp, "%d\t%s\n", in->a, in->b);
fclose(fp);
return 0;
}

我的 Python 代码:

...
from ctypes import *
...
class TEST_STRUCT(Structure):
_fields_ = [("a", c_int),
("b", c_char_p)]
...
hello_lib = ctypes.cdll.LoadLibrary("hello.so")
hello = hello_lib.hello
hello.argtypes = [POINTER(TEST_STRUCT)]
name = create_string_buffer(b"test")
hello_args = TEST_STRUCT(1, name)
hello(ctypes.byref(hello_args))
...

我得到错误: hello_args = TEST_STRUCT(1, 名称)类型错误:预期的字符串,找到 c_char_Array_5

我试过把c_char_p改成c_wchar_p或c_char*5或c_wchar*5等,有时能正常运行,struct的第一个int参数能正确打印,但第二个string指针不行,我能做到的最好get 只是第一个字符“t”而不是整个单词“test”。

顺便说一句,我的python3版本是3.3.0

最佳答案

解决方案取决于您是否需要数据类型可变(从 Python 的角度来看)。

如果不需要数据是可变的,那么不要为缓冲区构造函数操心。只需将 bytes 对象直接传递给 TEST_STRUCT 构造函数即可。例如。

from ctypes import *

class TEST_STRUCT(Structure):
_fields_ = [("a", c_int),
("b", c_char_p)]

hello_args = TEST_STRUCT(1, b"test")

如果您需要一个可变缓冲区,那么您需要在 TEST_STRUCT 类中以稍微不同的方式指定您的 char* 类型。例如。

from ctypes import *

class TEST_STRUCT(Structure):
_fields_ = [("a", c_int),
("b", POINTER(c_char))] # rather than c_char_p

name = create_string_buffer(b"test")
hello_args = TEST_STRUCT(1, name)

c_char_pPOINTER(c_char)

从表面上看,虽然这两者看起来很相似,但它们之间存在细微差别。 POINTER(c_char) 适用于 char 数据的任何缓冲区。 c_char_p 专门用于以 NULL 结尾的字符串。作为此条件的副作用,所有 c_char_p 对象都是不可变的(在 python 端),以便更容易执行此保证。例如。 {65, 66, 67, 0} 是一个字符串 ("ABC"),而 {1, 2, 3} 不是.

关于python - 使用 ctypes 将字符串从 Python 传递到 C 共享库的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38152036/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com