#ifndef PROTOCOL_H #define PROTOCOL_H /////////////////////////////////////////////////////////////////////////// // protocol.hpp - define protocol class // // // // this is all the client knows about the protocol, e.g., the language // // // // Jim Fawcett, CSE791 - Distributed Objects, Demonstration // /////////////////////////////////////////////////////////////////////////// /* design note: ------------ Protocol class hierarchies (sometimes called homeomorphic class structures) consist of an abstract base class and usually a single layer of derived classes. The base class provides a language, or protocol, for client access to all the derived classes. Clients know only the protocol, but not any of the details which distinguish one class from another. The derived classes provide all of the real functionality. The client code, however, does not need to know how any of the derived classes do their business. In this demonstration the member functions getInt() and putInt() are pure virtual functions so protocol class is an abstract base class. No protocol objects can be created. Only objects of derived classes which give definitions for both the pure virtual functions are concrete and can create objects. However, since the make_d1() and make_d2() protocol member functions are static they don't need objects to invoke them. Client code can do that with the syntax protocol::make_d1(), etc. So, we can invoke static members of an abstract class. We do just that in the client code in protocol.cpp +-----------+ | protocol | +-----+-----+ | / \ +--------------+--------------+ | | | +-----+-----+ +-----+-----+ +-----+-----+ | derived1 | | derived2 | | more der | +-----------+ +-----------+ +-----------+ /* // /* Implementation Issues: ====================== For this project to work correctly you must: - Use the DLL version of the C/C++ library for both client and DLLS (that ensures that both client and DLLs will use the same heap). - You do that by going to the project settings \ C/C++ tab and in the category combo box set Code Generation. Then in the Use Run-time Library combo box select one of the DLL libraries, e.g., either Multi-Threaded DLL or Debug Multi-threaded DLL. Do this for client and all DLLs. - After every build of the DLLs you must copy their dll files and lib files into the client's project directory, so the client can find them at load time. - To build from the command line you can use: cl /GX /LDd /MDd derived1.cpp cl /GX /LDd /MDd derived2.cpp cl /GX /MDd client.cpp derived1.lib derived2.lib - Alternately, you can use: msdev derived1.dsp /make /rebuild msdev derived2.dsp /make /rebuild msdev client.dsp /make /rebuild with project settings as described above. */ #ifdef IN_DLL #define DLL_DECL __declspec(dllexport) #else #define DLL_DECL __declspec(dllimport) #endif typedef std::string stdStr; class protocol { public: virtual DLL_DECL int getInt() = 0; virtual DLL_DECL void putInt(int) = 0; virtual DLL_DECL std::string passVal(std::string s) = 0; virtual DLL_DECL std::string passRef(std::string &s) = 0; static DLL_DECL protocol* make_d1(); static DLL_DECL protocol* make_d2(); }; #endif