目錄:java
2. 建立Feature變量post
4. 添加初始化code
源碼裏是有Feature的示例的,但當本身寫一個本身的Feature時,卻遇到了各類問題,有些是示例代碼和文檔沒有說明的小坑,這裏記錄一下。因源碼裏的startup目錄沒有任何代碼,就選擇它來存放代碼。開發
1. BUILD.gn文件裏的source_set("startup")須要修改爲 static_library("startup")。文檔
source_set 應該是不會打包進去仍是什麼,代碼不會被執行,修改爲static_library發現bin文件也增大了一些。字符串
2. 使用SYSEX_FEATURE_INIT(Init);進行初始化便可,可不使用SYS_RUN()和CORE_INI()宏。get
3. 直接使用SAMGR_GetInstance()->RegisterFeature(),並不能啓動Feature。Feature的啓動須要配全Service一塊使用,在使用SAMGR_GetInstance()->RegisterFeature()前須要先SAMGR_GetInstance()->RegisterService()註冊一個同命的Service才行。這點是最坑的地址,註冊Feature時參數是Service名稱字符串,因此就很容易想到直接註冊就能夠了,結束事實證實這樣是行不通的。源碼
4. 頭文件的順序,#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能被正常初始化了。固然上面只是貼出了核心代碼,聲明的方法仍是須要再實現一下的,下面是完整的代碼。
#include <stdio.h> #include <unistd.h> #include <ohos_init.h> #include <securec.h> #include <los_base.h> #include <cmsis_os.h> #include "iunknown.h" #include "feature.h" #include "service.h" #include "samgr_lite.h" #include "time_adapter.h" #include "discovery_service.h" #define EXAMPLE_SERVICE "example" #define EXAMPLE_FEATURE "example" struct Payload{ int id; const char *name; int value; }; 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); static int g_regStep=0; static const char *GetName(Service *service) { (void)service; printf("GetService name:"); return EXAMPLE_SERVICE; } static BOOL Initialize(Service *service, Identity identity) { (void)identity; printf("[Boot Test][TaskID:%p][Step:%d][Reg Finish S:%s]Time: %llu!\n", osThreadGetId(), g_regStep++, service->GetName(service), SAMGR_GetProcessTime()); return TRUE; } static BOOL MessageHandle(Service *service, Request *msg) { printf("[Boot Test][TaskID:%p][Step:%d][S:%s] msgId<%d> \n", osThreadGetId(), g_regStep++, service->GetName(service), msg->msgId); return FALSE; } static TaskConfig GetTaskConfig(Service *service) { (void)service; TaskConfig config = {LEVEL_HIGH, PRI_ABOVE_NORMAL, 0x400, 2, SHARED_TASK}; return config; } static Service g_exampleService={ .GetName=GetName, .Initialize=Initialize, .MessageHandle=MessageHandle, .GetTaskConfig=GetTaskConfig }; static DemoFeature g_example={ .GetName=FEATURE_GetName, .OnInitialize = FEATURE_OnInitialize, .OnStop = FEATURE_OnStop, .OnMessage = FEATURE_OnMessage, DEFAULT_IUNKNOWN_ENTRY_BEGIN, .AsyncCall=AsyncCall, .SyncCall=SyncCall, DEFAULT_IUNKNOWN_ENTRY_END, .identity = {-1, -1, NULL} }; static const char* FEATURE_GetName(Feature *feature) { printf("get feature name."); (void)feature; return EXAMPLE_FEATURE; } static void FEATURE_OnInitialize(Feature *feature, Service *parent, Identity identity) { printf("Register Test,Oninit1"); (void)parent; DemoFeature *demoFeature=(DemoFeature*)feature; demoFeature->identity=identity; printf("Register Test,Oninit"); } static void FEATURE_OnStop(Feature *feature, Identity identity) { (void)feature; (void)identity; g_example.identity.queueId = NULL; g_example.identity.featureId = -1; g_example.identity.serviceId = -1; } static BOOL FEATURE_OnMessage(Feature *feature, Request *request) { (void)feature; (void)request; printf("[LPC Test][TaskID:%p][Step:%d][OnMessage S:%s, F:%s] Inner Error! \n", osThreadGetId(), g_regStep++, EXAMPLE_SERVICE, feature->GetName(feature)); return FALSE; } static BOOL SyncCall(IUnknown *iUnknown, struct Payload *payload) { (void)iUnknown; if (payload != NULL && payload->id >= 0 && payload->name != NULL) { printf("[LPC Test][TaskID:%p][Step:%d][SyncCall API] Id:%d, name:%s, value:%d \n", osThreadGetId(), g_regStep++, payload->id, payload->name, payload->value); return TRUE; } printf("[LPC Test][TaskID:%p][Step:%d][SyncCall API] Input Error! \n", osThreadGetId(), g_regStep++); return FALSE; } static BOOL AsyncCall(IUnknown *iUnknown, const char *body) { Request request = {.msgId = 1, .msgValue = 0}; request.len = (uint32_t)(strlen(body) + 1); request.data = malloc(request.len); if (request.data == NULL) { return FALSE; } if (strcpy_s(request.data, request.len, body) != EOK) { free(request.data); return FALSE; } DemoFeature *feature = GET_OBJECT(iUnknown, DemoFeature, iUnknown); printf("[LPC Test][TaskID:%p][Step:%d][AsyncCall API] Send request! \n", osThreadGetId(), g_regStep++); return SAMGR_SendRequest(&feature->identity, &request, NULL); } static void OnPublishSuccess(int32_t publishId){ printf("demo service publish success.%d",publishId); } static void onPublishFail(int32_t publishId, PublishFailReason reason) { printf("OnPublishFail.%d,%d",publishId,(int32_t)reason); } //初始化工做,註冊Service後,再註冊Feature static void Init(void) { SAMGR_GetInstance()->RegisterService(&g_exampleService); SAMGR_GetInstance()->RegisterFeature(EXAMPLE_SERVICE,(Feature*)&g_example); SAMGR_GetInstance()->RegisterFeatureApi(EXAMPLE_SERVICE,EXAMPLE_FEATURE,GET_IUNKNOWN(g_example)); printf("[Register Test][TaskID:%d][Step:%d][Reg S:%s, F:%s] Time: %llu!\n", osThreadGetId(),g_regStep++,EXAMPLE_SERVICE,EXAMPLE_FEATURE,SAMGR_GetProcessTime()); } //使用此方式初始化Feature SYSEX_FEATURE_INIT(Init);
做者:mb5f8960971f61a
想了解更多內容,請訪問: 51CTO和華爲官方戰略合做共建的鴻蒙技術社區https://harmonyos.51cto.com