web-dev-qa-db-ja.com

ctypesを使用してpython文字列オブジェクトをc char *に変換する

Python(3.2)からctypesを使用してCに2つの文字列を送信しようとしています。これは、Raspberry Pi上のプロジェクトの一部です。C関数が文字列を正しく受信したかどうかをテストするには、それらの1つをテキストファイルに配置します。

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..
}

問題

文字列の最初の文字のみがテキストファイルに表示されます。

私はPython文字列オブジェクトをctypesで変換する多くの方法を試しました。

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

これらの変換により、「間違ったタイプ」または「strインスタンスの代わりに予期されるバイトまたは整数アドレス」というエラーが発生し続けます。

誰かがどこが悪いのか教えてくれるといいのですが。前もって感謝します。

19
LittleOne

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_char_p]
my_c_function(b_string1, b_string2)
21
LittleOne

Create_string_buffer()の代わりにc_char_p()を使用する必要があるだけだと思います。

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にキャストします。

11
Aksel

[〜#〜] 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')が必要かどうかはわかりません。

1
user4113344