libmqmsgque is using a class-attribute as instance-storage.
libmqmsgque is using a class-attribute as instance-storage.
To create a new instance-storage 3 steps are reqired:
typedef struct MyLoopServerS { struct MqContextS mqctx; ///< link to the \libmqmsgque object #define mydata_size 30 char mydata[mydata_size]; ///< define the "mydata" attribute } MyLoopServerC;
// initialize the MyLoopServer class-type with existing MqContextC_TT class-type MyLoopServerCTT = MkTypeDup2(MqContextC_TT,"MyLoopServerC"); MyLoopServerCTT->objsize = sizeof(struct MyLoopServerS);
enum MkErrorE MyLoopServerFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { // create new instance using the MyLoopServerCTT class-type MQ_CTX const mqctx = *contextP = MqContextCreate(MyLoopServerCTT,tmpl); // initialize the new context MqConfigSetServerSetup (mqctx, ServerSetup, NULL, NULL, NULL); // cast the libmqmsgque-context into the MyLoopServerC-context MyLoopServerC* mqctxC = (MyLoopServerC*)mqctx; // initialize the "mydata" attribute strncpy(mqctxC->mydata,"Hello World",mydata_size); mqctxC->mydata[mydata_size-1] = '\0'; return MK_OK; }
Example from MyLoopServer.c
→ create and access class-attribute mydata as instance-storage
#include "common.h" // [MyLoopServerC_Define] typedef struct MyLoopServerS { struct MqContextS mqctx; ///< link to the \libmqmsgque object #define mydata_size 30 char mydata[mydata_size]; ///< define the "mydata" attribute } MyLoopServerC; // [MyLoopServerC_Define] // the MyLoopServerC class-type static MkThreadLocal MK_TYP MyLoopServerCTT = NULL; // service to serve all EXTERNAL requests for token "HLWO" static enum MkErrorE HLWO_srv ( MQ_SERVICE_CALL_ARGS ) { // get the "loopback" context MQ_CTX loop = MqSlaveGet_e(mqctx,MQ_SLAVE_LOOPBACK); // call the LOOP service on the SAME server MqSend_E(loop,"W","LOOP"); // answer HLWO with string-return from LOOP MqSend_E(mqctx, "R", "C", MqReadSTR_e(loop)); return MK_OK; error: return MqSendRETURN(mqctx); } // service to serve all INTERNAL requests for token "LOOP static enum MkErrorE LOOP_srv ( MQ_SERVICE_CALL_ARGS ) { // get the "master" context MyLoopServerC* master = (MyLoopServerC*)MqSlaveGetMaster(mqctx); // answer LOOP with data from MASTER->mydata attribute return MqSend(mqctx, "R", "C", master->mydata); } // define a service as link between the token "HLWO" and the callback "HLWO_srv" static enum MkErrorE ServerSetup ( MQ_SERVICE_CALL_ARGS ) { // EXTERNAL: link the "HLWO" service with "HLWO_srv" MqServiceCreate_E(mqctx, "HLWO", HLWO_srv, NULL, NULL, NULL); // INTERNAL: link the "LOOP" service with "LOOP_srv" MqServiceCreate_E(MqSlaveGet_e(mqctx,MQ_SLAVE_LOOPBACK), "LOOP", LOOP_srv, NULL, NULL, NULL); return MK_OK; error: return MkErrorStack_1X(mqctx); } // [MyLoopServerC_Create] enum MkErrorE MyLoopServerFactory ( MQ_CALLBACK_FACTORY_CTOR_ARGS ) { // create new instance using the MyLoopServerCTT class-type MQ_CTX const mqctx = *contextP = MqContextCreate(MyLoopServerCTT,tmpl); // initialize the new context MqConfigSetServerSetup (mqctx, ServerSetup, NULL, NULL, NULL); // cast the libmqmsgque-context into the MyLoopServerC-context MyLoopServerC* mqctxC = (MyLoopServerC*)mqctx; // initialize the "mydata" attribute strncpy(mqctxC->mydata,"Hello World",mydata_size); mqctxC->mydata[mydata_size-1] = '\0'; return MK_OK; } // [MyLoopServerC_Create] int main (int argc, MK_STRN argv[]) { AllRtSetup_NULL; // [MyLoopServerC_Init] // initialize the MyLoopServer class-type with existing MqContextC_TT class-type MyLoopServerCTT = MkTypeDup2(MqContextC_TT,"MyLoopServerC"); MyLoopServerCTT->objsize = sizeof(struct MyLoopServerS); // [MyLoopServerC_Init] // setup commandline arguments for later use MK_BFL largv = MkBufferListCreateVC(argc, argv); MQ_CTX mqctx = NULL; // create "MyLoopServer" factory… and make it to the default. MqFactoryDefault(MqFactoryAdd_2(MyLoopServerFactory,"MyLoopServer")); // inspect commandline-argument for the "factory" to choose… and create a object MqFactoryNew_E (MqFactoryGetCalledL(largv), NULL, &mqctx); // start listen for incoming call's MqLinkCreate_E (mqctx, largv); MqCheckForLeftOverArguments_E (mqctx, largv); MqProcessEvent_E (mqctx,MQ_WAIT_FOREVER,MK_TIMEOUT_DEFAULT); error: MkBufferListDelete(largv); MqExit_1(mqctx); }