使用 ctypes 将 python 字符串对象转换为 c char*

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

我正在尝试使用 ctypes 将 2 个字符串从 Python (3.2) 发送到 C。这是我的 Raspberry Pi 项目的一小部分。为了测试 C 函数是否正确接收字符串,我将其中之一放入文本文件中。

Python代码

string1 = "my string 1"
string2 = "my string 2"

# create byte objects from the strings
b_string1 = string1.encode('utf-8')
b_string2 = string2.encode('utf-8')

# send strings to c function
my_c_function(ctypes.create_string_buffer(b_string1),
              ctypes.create_string_buffer(b_string2))

C代码

void my_c_function(const char* str1, const char* str2)
{
    // Test if string is correct
    FILE *fp = fopen("//home//pi//Desktop//out.txt", "w");
    if (fp != NULL)
    {
        fputs(str1, fp);
        fclose(fp);
    }

    // Do something with strings..
}

问题

文本文件中仅出现字符串的第一个字母。

我尝试了很多方法用ctypes转换Python字符串对象。

  • ctypes.c_char_p
  • ctypes.c_wchar_p
  • ctypes.create_string_buffer

通过这些转换,我不断收到错误“类型错误”或“需要字节或整数地址而不是 str 实例”。

我希望有人能告诉我哪里出了问题。 预先感谢。

c string python-3.x ctypes
3个回答
49
投票

感谢 Eryksun 的解决方案:

Python代码

string1 = "my string 1"
string2 = "my string 2"

# create byte objects from the strings
b_string1 = string1.encode('utf-8')
b_string2 = string2.encode('utf-8')

# send strings to c function
my_c_function.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
my_c_function(b_string1, b_string2)

20
投票

我认为你只需要使用 c_char_p() 而不是 create_string_buffer()。

string1 = "my string 1"
string2 = "my string 2"

# create byte objects from the strings
b_string1 = string1.encode('utf-8')
b_string2 = string2.encode('utf-8')

# send strings to c function
my_c_function(ctypes.c_char_p(b_string1),
              ctypes.c_char_p(b_string2))

如果您需要可变字符串,请使用 create_string_buffer() 并使用 ctypes.cast() 将它们转换为 c_char_p。


1
投票

您是否考虑过使用SWIG?我自己还没有尝试过,但在不更改 C 源代码的情况下,它会是什么样子:

/*mymodule.i*/

%module mymodule
extern void my_c_function(const char* str1, const char* str2);

这将使你的 Python 源代码变得简单(跳过编译):

import mymodule

string1 = "my string 1"
string2 = "my string 2"
my_c_function(string1, string2)

注意,如果您的源文件已经是 UTF-8,我不确定

.encode('utf-8')
是否必要。

© www.soinside.com 2019 - 2024. All rights reserved.