This sample program is for Microsoft Windows developers, and shows how the class library can be used with the MFC to provide a user interface. For more information, please see the detailed comments in each program and the documentation for each class library function.
/******************************************************************** // Multithreading server test program. // Multithreading only works for systems running 32-bit Windows. // To write a multithreading server program for a server function // derived from CRfcServerFunc, you need to implement a clone // function. This clone function needs to dynamically duplicate // itself. // Before you begin, define a copy constructor for your derived // class. This makes it easier to implement the clone function. // Please see the code example below if you need more information. // // To use the multihreading server feature, follow this step-by-step // example: // // (1) Derive a class from CRfcServerFunc. In this example, it is // called CRfcShow. // (2) Derive a class from CRfcServerApp. In this example, it is // called CRfcMyApp. // (3) In the CRfcShow class, define your own import, export, and // table // parameters. // (4) Implement the virtual functions CRfcShow::Process(void) and // CRfcShow::GetDescription (void). // (5) Implement a constructor, copy constructor, and a destructor // for CRfcShow. // (6) Implement the function CRfcServerFunc::clone in the CRfcShow // class. We did not define it as a pure virtual function // because we do not want to force non-multithreading server // users to implement it. However, if you want to use the // multithreading feature, you will receive an error if you // implement this clone function in your derived class (for // example, CRfcShow). // (7) If you just want to use the multithreading server feature, // then you do not need to define anything for CRfcMyApp. If // this is the case, you can go directly to step 8. However, // if you also want your application to work using a single // thread, then you need to implement CRfcMyApp::OnIdle(). // // Warning: If you do not implement this function, and you // design your application to use a single thread, your // application will take over most of your available CPU! // // (8) Create a CRfcConnection object, a CRfcMyApp object, and a // CRfcShow object. // (9) Connect to the R/3 system by calling CRfcConnection::Accept // (argv), where argv is the command line argument. // (10) Install the RFC function by calling // CRfcServerApp::AddServerFunction (RfcShow), where RfcShow is // an object of CRfcShow. // (11) Call CRfcServerApp::Run(nThreads), where nThreads is the // number of child threads you want. // // Note: If you enter a zero or no input as the value of // nThreads, the application will not use multithreading. // // Tips for Selecting the Number of Threads // // Case 1: The server has only one CPU. It is very unlikely that // more than one client will call this server // simultanously. If so, do NOT use multithreading. You // can call Run without an argument, or use zero as the // argument. // Case 2: The server has more than one CPU. Usually, there will // be only one client at a time calling this server. Do // NOT use multithreading. // Case 3: The server has more than one CPU. There might be more // than one client calling the server simultaneously. // However, the number of clients is usually smaller than // the number of CPUs. Set the number of child threads, // nThreads, equal to the number of CPUs. // Case 4: The server has one or more CPUs. Usually, the number of // clients calling the server is greater than the number of // CPUs. In this instance, you need to select the number of // child threads experimentally. ********************************************************************/
#if !defined(CRSERVTH_H) #define CRSERVTH_H #include "CRfcglob.h" #include "CRfclass.h" #if defined(_WIN32) || defined(SAPonNT) #define CRFCwithTHREADS #include <conio.h> #endif
void DumpErrorInfo (RFC_ERROR_INFO& err) { CRfcString errMessage; errMessage = "RFC Error: \nKey:"; errMessage += err.key; errMessage += "\nStatus:"; errMessage += err.status; errMessage += "\nMessage:"; errMessage += err.message; printf("%s\n\n", errMessage); } void get_passwd(char * pwd); class CrServTh { // Construction public: CrServTh(void); // standard constructor ~CrServTh(void); void DoMultithreading(char** argv, int nThreads=0); private: void StartThreads(char** argv, int nThreads=0); }; const int TEXT_LEN = 80 ; // Declare the server function. // The import data for this function is that for the RFC function // called by this server. This server will then get the export and // table data, and pass it to the clients. class CRfcMyApp; class CRfcShow: public CRfcServerFunc { // constructor & destructor public: CRfcShow() ; CRfcShow(CrServTh * pServTh, CRfcMyApp *pApp) ; ~CRfcShow() ; //Attributes protected: CRfcSimpleParam* m_pSimTitle ; CRfcSimpleParam* m_pSimCount ; CRfcTableParam * m_pTabContents ; CrServTh * m_pServTh; CRfcMyApp * m_pApp; void ClearParams(void); public: //Process() is declared as pure virtual, //so it must be implemented by users. void Process (void) ; CRfcServerFunc * clone() {return new CRfcShow(*this);} //This function must be implemented in the derived class of //CRfcServerFunc to make multithreading work CRfcShow(const CRfcShow & pShow); //This copy constructor must be implement to make the above //clone function work //Documenting the function object so that infomation about //the function is available when requested from R/3 System char* GetDescription (void) ; void SetnThreads(int nThreads) {m_nThreads = nThreads;} private: //Table filed information about CONTENTS static RFC_FIELD_INFO FieldsCONTENTS[] ; int m_nThreads; }; //Declare the server app class CRfcMyApp: public CRfcServerApp { // constructor & destructor public: CRfcMyApp(CRfcConnection* pConnection = NULL) ; ~CRfcMyApp() ; void OnIdle(); void EnableIdlePrint(); private: BOOL m_bPrintWait; }; #if defined(SAPonHPPA) template class CRfcList<CRfcString>; #endif #endif !defined(CRSERVTH_H) |