micropython用c添加接口——给module添加function

上一篇我们已经给micropython添加好了一个自定义的module:modtest,但是没有实现任何功能,这一篇就讲讲如何给modtest添加function功能。

函数是分为有参数和无参数的,那么我们就来添加两个function,一个没有参数的,一个有一个参数的。

第一种,先来添加无参数的函数,我们给他起名为test0(这个名字是最终在python层面显示的)。

下面我们先看代码再解释:

//这是我们定义函数
STATIC mp_obj_t modtest_test0()
{
    printf("This is motest function :test0\n");
    return mp_const_none;//不需要返回数据就返回它
}
//每一个我们和python接口的函数都需要使用这个宏定义
STATIC const MP_DEFINE_CONST_FUN_OBJ_0(modtest_obj_test0,modtest_test0);

STATIC const mp_rom_map_elem_t modtest_globals_table[] = {
    {MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_modtest)},
    {MP_OBJ_NEW_QSTR(MP_QSTR_test0), MP_ROM_PTR(&modtest_obj_test0)},    //这条是我们添加的,把新建的函数注册进modtest里面去
};

所有我们和python对接的函数都要是返回mp_obj_t类型的 ,如果该函数实际不需要返回任何数据我们最后就调用return mp_const_none;

比价重要的一条就是这个了STATIC const MP_DEFINE_CONST_FUN_OBJ_0(modtest_obj_test0,modtest_test0);    micropython针对不同参数类型提供了好几个这种类似的宏定义。这里不深做解释,我们是用的OBJ_0就是代表改函数是0个参数的。

最后一步就是把我们定义的function注册进modtest_globals_table中去,和前面注册module类型类似,MP_QSTR_test0   该名称中的test0会作为我们在pythonfunction显示的名字。

这样就算添加好了,编译烧录看结果:

micropython用c添加接口——给module添加function

可以看到python层我们调用 modtest.test0()就可以执行到我们函数中打印的内容。

这里还有个坑需要注意一下,在接口函数里面调用printf的时候,最后的’\n’要加上,要不然打印不出来。

 

第二种:添加一个带有一个参数的函数接口

有了前面的例子,添加带有一个接口的函数就更容易理解了,可以重点看和不带参数的区别,先上代码:

//参数类型要用mp_obj_t
STATIC mp_obj_t modtest_test1(mp_obj_t data)
{
    printf("This function have one parameters: %d\n",mp_obj_get_int(data));  //请注意这里从参数中提取整数使用的方法
    return mp_const_none;  //同样没有返回值
}
//这里使用的宏定义和面的名称不一样,OBJ_1区别
STATIC const MP_DEFINE_CONST_FUN_OBJ_1(modtest_obj_test1,modtest_test1);

STATIC const mp_rom_map_elem_t modtest_globals_table[] = {
    {MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_modtest)},
    {MP_OBJ_NEW_QSTR(MP_QSTR_test0), MP_ROM_PTR(&modtest_obj_test0)},
    {MP_OBJ_NEW_QSTR(MP_QSTR_test1), MP_ROM_PTR(&modtest_obj_test1)},    //把新定义的函数注册进modtest_globals_table
};

看起来是不是大同小异,定义的函数我们添加了一个mp_obj_t 类型的参数,实际上mp_obj_t 就是一个空指针,这样他可以用来传递任何类型,不管是整数,字符串都可以。具体是什么类型我们在函数内部用mp提供的对应的方法把他提取出来,比如这里认为传进来的是一个int型的,就是用mp_obj_get_int(data) 来提取出来整型。当然micopython还提供了很多其他类似的,需要注意一下是提取字符串的稍微形式上看起来有点区别:           mp_obj_str_get_str(arg)  。

接下来就是使用的宏定义不一样,这个是一个参数的就用MP_DEFINE_CONST_FUN_OBJ_1  (官方一共提供了七种接口,请自行慢慢研究)

后面注册的方式是一样的。好了,下面继续看编译烧录结果:

micropython用c添加接口——给module添加function

可以看到我们调用modtest.test1(100)已经成功把参数100传递了进去。

接下来是预告时间:下一篇会讲在module中添加type和在type中添加function的方法步骤


转载请注明转自电子创客营:micropython用c添加接口——给module添加function! 了解我们点击这里
喜欢 (3)or分享 (0)
电子创客营
关于作者:
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(5)个小伙伴在吐槽
  1. 楼主你好,我按你的方法,写了modtest.c 在编译的时候遇到错误: est.c:19:18: error: ‘MP_QSTR_test0’ undeclared here (not in a function) {MP_ROM_QSTR(MP_QSTR_test0), MP_ROM_PTR(&modtest_obj_test0)}, ^ ../../py/obj.h:92:56: note: in definition of macro ‘MP_OBJ_NEW_QSTR’ #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 2)) ^ modtest.c:19:6: note: in expansion of macro ‘MP_ROM_QSTR’ {MP_ROM_QSTR(MP_QSTR_test0), MP_ROM_PTR(&modtest_obj_test0)}, 看上去是没有在build/genhdr/qstrdefs.generated.h中生成test0对应的字符串,我是在port/minimal目录下面加的modtest.c. 能指点下还需要修改哪个地方吗? 3Q
    小木匠2018-11-01 17:13 回复 Windows 10 | Chrome 70.0.3538.77
    • 电子创客营
      首先你不加的时候要确保minimal 可以编译通过,然后再按照我这篇文章http://www.eemaker.com/micropython-add-module.html 确定添加一个module没问题,下一步再按照本片里面的添加一个function。这样确保你每一步都没有出错。如果中间还遇到编译不成功,建议把build文件夹删除再次编译
      电子创客营2018-11-12 09:49 回复 Windows 10 | Chrome 70.0.3538.77
      • 我这里试了,只有在 /py/qstrdefs.h 里面加上 Q(test0), build/genhdr/qstrdefs.generated.h里面才会生成MP_QSTR_test0, 暂时先用这方法来解决了。
        小木匠2018-11-12 11:09 回复 Windows 10 | Chrome 70.0.3538.77
  2. STATIC const MP_DEFINE_CONST_FUN_OBJ_0(modtest_obj_test0,modtest_test0); modtest_obj_test0 应当为 modtest_test0_obj
    turbo2018-10-19 20:15 回复 Windows 7 | Chrome 63.0.3239.132
    • 电子创客营
      不是的,这个名字你可以随便定义,只要不重复就行。所以我定义的方式没错,你的也可以编译通过,只要保证定义和使用的地方统一
      电子创客营2018-10-23 21:59 回复 Windows 10 | Chrome 69.0.3497.100