FeResPost Web Site                     FeResPost Online User Manual

VII.1.1.3 Using component with C++

The example is provided in the following files:

The batch file “COM/EX99_LANGS/build.bat” is used to compile the example. The compilation output should look as follows:

         g++ -c testClaCom.cpp -I"H:\OUTPUTS\COM\include"
         g++ -c util.cpp
         g++ -o testClaCom.exe testClaCom.o util.o \
            "H:\OUTPUTS\COM\lib\FeresPost.dll"  -lole32 -loleaut32 \
            -luuid -lstdc++
      

(You may need to change the compilation commands, options, and file paths to compile the program on your computer.)

In a C++ program, several headers must first be included to gain access to the class, method, and GUID declarations and/or definitions:

         #include <Application.hxx>
         #include <Application_i.c>

         #include <ClaDb.hxx>
         #include <ClaLam.hxx>
         #include <ClaMat.hxx>
         #include <ClaLoad.hxx>
         #include <IterX.hxx>
         #include <Iterator.hxx>
      

(These header files are distributed with the FeResPost COM library, in the “include” directory.) The component is accessed and initialized as follows:

      if (!CoInitialize(0)){
         if ((hr = CoGetClassObject(CLSID_Application, CLSCTX_INPROC_SERVER,
                  0, IID_IClassFactory, (LPVOID *)&classFactory))) {
            MessageBox(0, "Can’t get IClassFactory", "CoGetClassObject error",
                  MB_OK|MB_ICONEXCLAMATION);
            cerr << hr << endl ;
            exit(-1);
         }
         else {
            if ((hr = classFactory->CreateInstance(0, IID_IApplication,
                     (LPVOID *)&frpApp))) {
               classFactory->Release();
               MessageBox(0, "Can’t create IApplication object",
                     "CreateInstance error",MB_OK|MB_ICONEXCLAMATION);
               return -1;
            }
            else {
               classFactory->Release();
               MessageBox(0, "SUCCESS", "SUCCESS", MB_OK|MB_ICONEXCLAMATION);
            }
         }
      }

      frpApp->newObject(BSTR_ClaDb,(IDispatch**)&db);
      string2variant("test.ndf",fileName);
      db->readNeutral(fileName);
      

As you can see, this is somewhat more complicated than in Ruby or Python.

The complete C++ example shows that using the COM component is significantly more complicated with compiled languages than with interpreted languages that support COM automation. This is due to several factors:

To illustrate these points, here is an example of the code required to iterate over laminate and load IDs and call the calculation functions:

         VARIANT lamId,loadId;
         IIterator *lamIt,*loadIt;
         IIterX *lamIterX,*loadIterX;
         ULONG pCeltFetched;

         ...

         db->get_iter_laminateId((IDispatch**)&lamIt);
         lamIt->get_newEnum((IUnknown**)&lamIterX);
         db->get_iter_loadId((IDispatch**)&loadIt);
         loadIt->get_newEnum((IUnknown**)&loadIterX);
         lamIterX->Reset();
         for (lamIterX->Next(1,&lamId,&pCeltFetched);pCeltFetched>0;
               lamIterX->Next(1,&lamId,&pCeltFetched)) {
            printLamProperties(db,os,lamId);
            loadIterX->Reset();
            for (loadIterX->Next(1,&loadId,&pCeltFetched);pCeltFetched>0;
                  loadIterX->Next(1,&loadId,&pCeltFetched)) {
                     printLoadResponse(db,os,lamId,loadId,0.0,criteria);
            }
         }
         lamIterX->Release();
         lamIt->Release();
         loadIterX->Release();
         loadIt->Release();
      

In fact, this example shows that the component is best suited for use with languages that support the Microsoft IDispatch interface. A library adapted for use with C++ should also be developed; in the meantime, it is not recommended to use the component from C++ or C.