All non-multithreading class library programs can run on both 32-bit Windows and UNIX platforms. This sample program is for Microsoft Windows developers. The program 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.
/////////////////////////////////////////////////////// // CrServTh.cpp : implementation file /////////////////////////////////////////////////////// #include "CrServTh.h" CSAPCriticalSection CrServThLock; extern CRfcTrace RfcClassTrace; // For debugging trace main( int argc, char ** argv) { CrServTh servThObj; char inputBuffer[MAX_LEN]; int nThreads = 0; memset(inputBuffer, 0, MAX_LEN); printf("\n\nPlease enter the number of child threads for the server (default is zero): "); gets(inputBuffer) ; if (strlen(inputBuffer) == 0) nThreads = 0; else { nThreads = atoi(inputBuffer); if (nThreads < 0) nThreads = 0; } servThObj.DoMultithreading(argv, nThreads); return 0; } // Get destination, client, user name, password, and functional name // for Logon CrServTh::CrServTh() { } CrServTh::~CrServTh() { } // Get data from R/3 and display on screens void CrServTh::DoMultithreading(char** argv, int nThreads) { RfcClassTrace.Trace("Now in CrServTh::DoMultithreading"); #if !defined(CRFCwithTHREADS) nThreads = 0; #endif if(nThreads < 0) nThreads = 0; StartThreads(argv, nThreads); } // This method starts the mulithreading server void CrServTh::StartThreads(char** argv, int nThreads) { RfcClassTrace.Trace("Processing in CrServTh::StartThreads"); CRfcConnection Connection ; CRfcMyApp MyApp(&Connection); CRfcShow RfcShow(this, &MyApp);
int nSuccessThreads = 0; try { //Establish a connection to the R/3 system or the //R/3 gateway server depending on which mode is //used //_asm int 3; Connection.Accept (argv) ; //Register the RFC server function to the Server App //object //Server App object knows how to dispatch a call from //the R/3 System to the server function RfcShow.SetnThreads(nThreads); MyApp.AddServerFunction (RfcShow); //_asm int 3; //MyApp.Run() ; MyApp.Run(nThreads);
//_asm int 3; } catch(RFC_ERROR_INFO err) { DumpErrorInfo(err); } catch (char *pException) { printf("\n%s\n\n", pException); } } ///////////////////////////////////////////////////////// // Class definition for CRfcMyApp ///////////////////////////////////////////////////////// CRfcMyApp::CRfcMyApp (CRfcConnection* pConnection) :CRfcServerApp (pConnection), m_bPrintWait(TRUE) { } //Do something when the program receives no RFC call from the R/3 //system //(single threads only) void CRfcMyApp::OnIdle() { #ifdef SAPonUNIX sleep(1); #elif defined(SAPonNT) sleep(1000); #endif if(m_bPrintWait) { cout << endl << endl << endl << endl << "Waiting for call..." << endl << endl << flush; m_bPrintWait = FALSE; } } void CRfcMyApp::EnableIdlePrint(void) { m_bPrintWait = TRUE; } CRfcMyApp::~CRfcMyApp(void) { } ///////////////////////////////////////////////////////// // Class definiation for CRfcShow ///////////////////////////////////////////////////////// RFC_FIELD_INFO CRfcShow::FieldsCONTENTS[] = {{"TEXT", 0, 0, TYPC, 80, 0}} ; CRfcShow::CRfcShow (CrServTh * pServTh, CRfcMyApp *pApp) : CRfcServerFunc ("RFC_SHOW"), m_pServTh(pServTh), m_pApp(pApp), m_nThreads(0) { RfcClassTrace.Trace("Processing in CRfcShow::CRfcShow"); try { m_pSimTitle = new CRfcSimpleParam ("TITLE", TYPC, TEXT_LEN); //Must specify data type here m_pSimCount = new CRfcSimpleParam ("COUNT", TYPINT, sizeof(TYPINT)); m_pTabContents = new CRfcTableParam ("CONTENTS",TEXT_LEN) ; m_pTabContents->AddFieldInfo (FieldsCONTENTS, sizeof(FieldsCONTENTS) / sizeof(RFC_FIELD_INFO)) ; //Add parameters to the function object AddImportParam (*m_pSimTitle) ; AddExportParam (*m_pSimCount) ; AddTableParam (*m_pTabContents) ; } catch (char*) { printf("Memory error in CRfcShow::CRfcShow.\n\n"); ClearParams() ; } } CRfcShow::CRfcShow(const CRfcShow & pShow) : CRfcServerFunc(pShow) { m_pSimTitle = (CRfcSimpleParam *)GetImportParam("TITLE"); m_pSimCount = (CRfcSimpleParam *)GetExportParam("COUNT"); m_pTabContents = GetTableParam("CONTENTS"); m_pServTh = pShow.m_pServTh; m_pApp = pShow.m_pApp; m_nThreads = pShow.m_nThreads; } #if defined(CRFCwithTHREADS) extern int rfc_thread[10000]; //You do not have to know this, it is //for debugging only //Allows you to find out which threads //are performing which tasks. /*-----------------------------------------------------------*/ /* Macro for output RFC-Call on screen */ /*-----------------------------------------------------------*/ #define PRINT_RFC_CALL(thread_id, text) \ if (thread_id) \ printf("\n Thread %3d: %s", thread_id, text); \ else \ printf("\n Main Thread %s", text); \ fflush(stdout) #else #define PRINT_RFC_CALL(thread_id, text) \ printf("\n %s", text); \ fflush(stdout) #endif void CRfcShow::Process() { RfcClassTrace.Trace("Processing in CRfcShow::Process");
RFC_HANDLE RfcHandle; GET_VERIFIED_CONNECTION(RfcHandle); char dbuf[512]; memset(dbuf, 0, 511); int nRow; int nCount ; // Number of rows //Get row count for the table //Print out the title sprintf(dbuf, " Title: %s\n\n", (CSTR)m_pSimTitle->Value()); PRINT_RFC_CALL(rfc_thread[RfcHandle], dbuf); nCount = m_pTabContents->GetRowCount() ; for (nRow = 0; nRow < nCount; nRow++) { //A column can be specified by name or index. sprintf(dbuf, "%s\n", (CSTR)m_pTabContents->Cell(nRow, 0)); PRINT_RFC_CALL(rfc_thread[RfcHandle], dbuf); } m_pSimCount->Value() = nCount; if (m_nThreads == 0 && m_pApp) m_pApp->EnableIdlePrint(); } char* CRfcShow::GetDescription (void) { RfcClassTrace.Trace("Processing in CRfcShow::GetDescription"); static char docu[] = "RFC Server Sample program using the RFC class library." NL "EXPORTING" NL "m_nTableLines TYPC" NL "m_pChildThreads TYPC" NL "IMPORTING" NL "m_pCustNum TYPC" NL "m_pCustName TYPC" NL "TABLES" NL "m_pTabContents text" NL ; return docu; } void CRfcShow::ClearParams(void) { if (m_pSimTitle != NULL) delete m_pSimTitle ; if (m_pSimCount != NULL) delete m_pSimCount ; if (m_pTabContents != NULL) delete m_pTabContents ; m_pSimTitle = NULL; m_pSimCount = NULL; m_pTabContents = NULL; } CRfcShow::~CRfcShow() { ClearParams(); } |