スポンサーリンク

PythonからPybind11で作成したモジュールに文字列を渡すときの注意

Pythonの文字列はutf8で扱われているが、C++側はUnicodeに弱い。使用しているライブラリがマルチバイト(非utf8なstd::string)しか受け付けてないような場合はPython側でshift_jisに変換して渡してやると都合がいい。

#include <pybind11/pybind11.h>

#include <cstdio>


namespace py = pybind11; // 名前空間を指定


void func_setstring(std::string text) {

    FILE* fp = fopen("test.txt", "wb");
    if (fp == NULL) {
        return;
    }
    fwrite(text.c_str(), sizeof(char), text.size(), fp);
    fclose(fp);
}

// PYBIND11_MODULE(モジュール名, モジュール変数名)
// 生成物はmy_module_string.pydという名前にしなければならない
PYBIND11_MODULE(my_module_string, m) {

    // 関数を定義
    m.def("func_string", &func_setstring, "Write text to file",
        py::arg("text"));

}

Shift-JISで渡す

import my_module_string

text = "こんにちは、世界!"

# テキストを書き込む
my_module_string.func_string(text.encode("shift_jis"))

エディタで確認すると、SJISと判別されている。

UTF-8で渡す

そのまま渡すとutf-8で受け取る。C++はstd::stringでutf8を扱いたがるので紛らわしい。高度な文字列処理が必要ないならそのまま使用できる。ファイルに保存してやれば受け取った内容がutf-8であることをテキストエディタで確認できる。

import my_module_string

text = "こんにちは、世界!"

# テキストを書き込む
my_module_string.func_string(text)

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: