2
1

More than 3 years have passed since last update.

MicroPythonにCモジュールを追加するために...

Posted at

とりあえず簡単な関数を実装してみる。

どれもmicropythonでできることなのでCで実装する必要はないけど、
今後何かしらをCで実装する必要が出てきたときのために最低限の確認。

ドキュメントが見当たらなくてgitに上がっているmicropythonのコードを追いかけて実装したので別の方法があるかも...(ご存知の方はご指摘いただけると幸いです。)

  • 文字列を引数にとってリターン
STATIC mp_obj_t return_str(mp_obj_t str_obj)
{
    const char *str = mp_obj_str_get_str(str_obj);

    return mp_obj_new_str(str, strlen(str));
}

 list操作

  • 作成
STATIC mp_obj_t list_new()
{
    mp_obj_t list_items[] = {
        mp_obj_new_int(123),
        mp_obj_new_float(456.789),
        mp_obj_new_str("hello", 5),
    };

    return mp_obj_new_list(3, list_items);
}
  • append
//追加したいitemがint型の場合
STATIC mp_obj_t list_append(mp_obj_t list_obj, mp_obj_t item_int_obj)
{
    mp_int_t item_obj = mp_obj_get_int(item_int_obj);
    mp_obj_t item = mp_obj_new_int(item_obj);

    mp_obj_list_append(list_obj, item);

    return list_obj;
}
  • remove
// 削除したいitemがint型の場合
STATIC mp_obj_t list_remove(mp_obj_t list_obj, mp_obj_t item_int_obj)
{
    mp_int_t item_obj = mp_obj_get_int(item_int_obj);
    mp_obj_t item = mp_obj_new_int(item_obj);

    mp_obj_list_remove(list_obj, item);

    return list_obj;
}

dict操作

  • 作成
STATIC mp_obj_t dict_new()
{
    mp_obj_t dict_obj = mp_obj_new_dict(3);
    mp_obj_dict_store(dict_obj, mp_obj_new_str("test_key1", 9), mp_obj_new_int(123));
    mp_obj_dict_store(dict_obj, mp_obj_new_str("test_key2", 9), mp_obj_new_float(456.789));
    mp_obj_dict_store(dict_obj, mp_obj_new_str("test_key3", 9), mp_obj_new_str("hello", 5));

    return dict_obj;
}
  • 追加、変更
//追加したい要素が['str型': 'str型']の場合
STATIC mp_obj_t dict_store(mp_obj_t dict_obj, mp_obj_t key_str_obj, mp_obj_t value_str_obj)
{
    mp_obj_dict_get_map(dict_obj);
    const char *key = mp_obj_str_get_str(key_str_obj);
    const char *val = mp_obj_str_get_str(value_str_obj);

    mp_obj_dict_store(dict_obj, mp_obj_new_str(key, strlen(key)), mp_obj_new_str(val, strlen(val)));

    return dict_obj;
}
  • 削除
// 削除したいkeyがstr型の場合
STATIC mp_obj_t dict_delete(mp_obj_t dict_obj, mp_obj_t key_str_obj)
{
    mp_obj_dict_get_map(dict_obj);
    const char *del_key = mp_obj_str_get_str(key_str_obj);

    mp_obj_dict_delete(dict_obj, mp_obj_new_str(del_key, strlen(del_key)));

    return dict_obj;
}

MicroPythonから呼び出せるようにするには...

// 呼び出す関数
STATIC mp_obj_t return_str(mp_obj_t str_obj)
{
    const char *str = mp_obj_str_get_str(str_obj);

    return mp_obj_new_str(str, strlen(str));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(return_str_obj, return_str);

// モジュールとして定義
STATIC const mp_rom_map_elem_t example_module_globals_table[] = {
    // micropythonでimportするときの名前
    {MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_example)}, 
  // micropythonから関数を呼び出すときの名前
    {MP_ROM_QSTR(MP_QSTR_return_str), MP_ROM_PTR(&return_str_obj)},
};

STATIC MP_DEFINE_CONST_DICT(example_module_globals, example_module_globals_table);

const mp_obj_module_t example_cmodule = {
    .base = {&mp_type_module},
    .globals = (mp_obj_dict_t *)&example_module_globals,
};

上記のように.Cを作ってmicropythonのソースに追加してビルドする。
micropythonからは、

import example
example.return_str()

のようにして使う。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1