目录:
源码里是有Feature的示例的,但当自己写一个自己的Feature时,却遇到了各种问题,有些是示例代码和文档没有说明的小坑,这里记录一下。因源码里的startup目录没有任何代码,就选择它来存放代码。
- BUILD.gn文件里的source_set("startup")需要修改成 static_library("startup")。
source_set 应该是不会打包进去还是什么,代码不会被执行,修改成static_library发现bin文件也增大了一些。
- 使用SYSEX_FEATURE_INIT(Init);进行初始化即可,可不使用SYS_RUN()和CORE_INI()宏。
- 直接使用SAMGR_GetInstance()->RegisterFeature(),并不能启动Feature。Feature的启动需要配全Service一块使用,在使用SAMGR_GetInstance()->RegisterFeature()前需要先SAMGR_GetInstance()->RegisterService()注册一个同命的Service才行。这点是最坑的地址,注册Feature时参数是Service名称字符串,所以就很容易想到直接注册就可以了,结束事实证明这样是行不通的。
- 头文件的顺序,#include <ohos_init.h>要在#include "hctest.h"之前,否则SYSEX_FEATURE_INIT引用的是hos_init.h里的声明,而不是ohos_init.h文件里的声明
下面看一下添加Feature的正确方式:
1. 创建Service变量
static const char *GetName(Service *service);
static BOOL Initialize(Service *service, Identity identity);
static BOOL MessageHandle(Service *service, Request *msg);
static TaskConfig GetTaskConfig(Service *service);
static Service g_exampleService={
.GetName=GetName,
.Initialize=Initialize,
.MessageHandle=MessageHandle,
.GetTaskConfig=GetTaskConfig
};
2. 创建Feature变量
这里定义Feature没有直接使用Feature进行定义,而是使用了源码示例中的另一种方式,即同类型定义。
typedef struct DemoApi{
INHERIT_IUNKNOWN;
BOOL (*AsyncCall)(IUnknown *iUnknown, const char *buff);
BOOL (*SyncCall)(IUnknown *iUnknown,struct Payload *payload);
} DemoApi;
typedef struct DemoFeature{
INHERIT_FEATURE;
INHERIT_IUNKNOWNENTRY(DemoApi);
Identity identity;
} DemoFeature;
static BOOL AsyncCall(IUnknown *iUnknown, const char *body);
static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload);
static const char* FEATURE_GetName(Feature *feature);
static void FEATURE_OnInitialize(Feature *feature, Service* parent, Identity identity);
static void FEATURE_OnStop(Feature *feature, Identity identity);
static BOOL FEATURE_OnMessage(Feature *feature, Request *request);
3. 注册Service&Feature
SAMGR_GetInstance()->RegisterService(&g_exampleService);
SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE,(Feature*)&g_example);
SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE,EXAMPLE_FEATURE,GET_IUNKNOWN(g_example));
4. 添加初始化
SYSEX_FEATURE_INIT(Init);
做完以上步骤后编译烧写到wifi-iot开发板后就可以看到Feature能被正常初始化了。当然上面只是贴出了核心代码,声明的方法还是需要再实现一下的,下面是完整的代码。
作者:mb5f8960971f61a
想了解更多内容,请访问: 51CTO和华为官方战略合作共建的鸿蒙技术社区https://harmonyos.51cto.com