#ifdef __WIN32 #include <windows.h> #endif #include <BipCos.h> #include <BipCci.h> #include <BipCni.h> #include <malloc.h> #define BIP_DEF_COMP_CCSID 437 CciChar* constNodeFactory = 0; CciChar* constNodeName = 0; CciChar* constTerminalName = 0; CciChar* constOutTerminalName = 0; CciChar* CciString( const char* source, int codepage ){ /* Maximale Zeichenanzahl bei Unicode-Darstellung */ int maxChars = strlen(source) + 1 ; CciChar* buffer = (CciChar*)malloc(maxChars * sizeof(CciChar)) ; int rc; cciMbsToUcs(&rc, source, buffer, maxChars, codepage) ; return buffer ; } void initNodeConstants(){ constNodeFactory = CciString("myNodeFactory", BIP_DEF_COMP_CCSID); constNodeName = CciString("myNode",BIP_DEF_COMP_CCSID); constTerminalName = CciString("in",BIP_DEF_COMP_CCSID); constOutTerminalName = CciString("out",BIP_DEF_COMP_CCSID); } typedef struct { CciTerminal* iOutTerminal; }MyNodeContext; CciContext* createNodeContext( CciFactory* factoryObject, CciChar* nodeName, CciNode* nodeObject ){ MyNodeContext * p = (MyNodeContext *)malloc(sizeof(MyNodeContext)); /*Hier kann eine Instanz einer beliebigen Datenstruktur erstellt werden, in der der Kontext dieser Knoteninstanz gespeichert werden kann. Dabei kann ein Zeiger an diese Struktur zurückgegeben werden, der anschließend an die anderen Implementierungsfunktionen übergegeben wird.*/ /* Jetzt kann ein Eingabeterminal für den Knoten erstellt werden.*/ cniCreateInputTerminal(NULL, nodeObject, (CciChar*)constTerminalName); p->iOutTerminal = cniCreateOutputTerminal(NULL, nodeObject, (CciChar*)constOutTerminalName); return((CciContext*)p); } /****************************************************************/ /* */ /* Implementierungsfunktion des Plug-in-Knotens: cniEvaluate() */ /* */ /****************************************************************/ void evaluate( CciContext* context, CciMessage* destinationList, CciMessage* exceptionList, CciMessage* message ){ /* Hier kann die Verarbeitungslogik des Knotens angegeben werden.*/ return; } int run( CciContext* context, CciMessage* destinationList, CciMessage* exceptionList, CciMessage* message ) { char* buffer="<doc><test>hello</test></doc>"; CciChar* wBuffer=CciString(buffer,BIP_DEF_COMP_CCSID); //cniSetInputBuffer(NULL,message,(void*)wBuffer,strlen(buffer) * sizeof(CciChar)); cniSetInputBuffer(NULL,message,(void*)buffer,strlen(buffer)); cniFinalize(NULL,message,0); cniPropagate(NULL,((MyNodeContext*)context)->iOutTerminal,destinationList,exceptionList,message); return CCI_SUCCESS_CONTINUE; } #ifdef __cplusplus extern "C"{ #endif CciFactory LilFactoryExportPrefix * LilFactoryExportSuffix bipGetMessageflowNodeFactory() { CciFactory* factoryObject; /* Vor dem Fortfahren müssen alle statischen Konstanten initialisiert werden, */ /* die unter Umständen von dem Plug-in verwendet werden. */ initNodeConstants(); /* Erstellen Sie die Knoten-Factory für dieses Plug-in*/ /* Wenn Fehler/Ausnahmebedingungen */ /* während der Ausführung dieser Dienstprogrammfunktion auftreten, wird die Ausnahmebedingung */ /* auf Grund der Auslassung des Arguments 'returnCode' das Plug-in übergehen */ /* und direkt vom Broker verarbeitet werden. */ factoryObject = cniCreateNodeFactory(0, (unsigned short *)constNodeFactory); if (factoryObject == CCI_NULL_ADDR) { /* Die Behandlung weiterer lokaler Fehler kann hier erfolgen */ } else { /* Definieren Sie den von der Factory unterstützten Knoten. */ static CNI_VFT vftable = {CNI_VFT_DEFAULT}; /* Definition der Funktionstabelle mit Zeigern zu Funktionen für Knotenimplementierung */ vftable.iFpCreateNodeContext = createNodeContext; vftable.iFpEvaluate = evaluate; vftable.iFpRun = run; /* Definieren Sie einen Knotentyp, der von unserer Factory unterstützt wird. Wenn Fehler/Ausnahmebedingungen */ /* während der Ausführung dieser Dienstprogrammfunktion auftreten, wird die Ausnahmebedingung */ /* auf Grund der Auslassung des Arguments 'returnCode' das Plug-in übergehen */ /* und direkt vom Broker verarbeitet werden. */ cniDefineNodeClass(NULL, factoryObject, (CciChar*)constNodeName, &vftable); } /* Rückkehradresse dieses Factory-Objekts zum Broker */ return(factoryObject); } #ifdef __cplusplus } #endif
Der folgende Code ist eine Makefile, in der die Dateien, Abhängigkeiten und Regeln aufgelistet sind, auf Grund derer der benutzerdefinierte C-Knoten kompiliert werden soll.
.SUFFIXES : .so .a .o .c R1INC = . R1LIB = . # WMQI MQSIDIR = /cmvc/back/inst.images/x86_linux_2/shipdata/opt/mqsi MQSIINC = $(MQSIDIR)/include MQSILIB = $(MQSIDIR)/lib # WMQ MQIDIR = /usr/mqm CC = /usr/bin/g++ LD = ${CC} OBJ = .o LIL = .lil THINGSTOCLEAN = *${OBJ} CFLAGS = -fpic -c #-pedantic -x c -Wall CFLAGSADD = -I${R1INC} -I${MQSIINC} -I${MQSIINC}/plugin ${DEFINES} DEFINES = -DLINUX LIBADD = -L${MQSILIB} -limbdfplg LDFLAG = -shared ${LIBADD} #CC = /usr/bin/gcc #LD = ${CC} OBJECTS = skeleton${OBJ} .c.o : ; ${CC} ${CFLAGS} ${CFLAGSADD} $< ALL : ${OBJECTS} Samples${LIL} clean: rm *${OBJ} *${LIL} skeleton${OBJ}: skeleton.c Samples${LIL}: ${OBJECTS} ${LD} -o $@ ${OBJECTS} ${LDFLAG}