Chapter 5 using Factories In Orbacus:
5.1 A Simple Factory Example:
Let's create a simple factory example using the
MyTime interface.
5.1.1 The New MyTime IDL:
As you can see from the interface listed below, much of this
interface looks quite familiar. The only new thing is the addition of
the Factory pattern interface.
frag1.cpp
1 interface MyTimeFactory{
2 MyTime CreateMyTime();
3 };
syntax highlighted by Code2HTML, v. 0.8.8b
We will develop a more complicated Factory example in a little bit where
the factory has more than one creation method, but for now let's
concentrate on this simpler form.
The full IDL for our sample application is then as follows:
Display2.idl
1 module Display2{
2 struct TimeOfDay{
3 short hour;
4 short minute;
5 short second;
6 };
7 interface MyTime{
8 TimeOfDay getgmt();
9 };
10 interface MyTimeFactory{
11 MyTime CreateMyTime();
12 };
13 };
syntax highlighted by Code2HTML, v. 0.8.8b
As usual, we generate our C++ code by running the IDL to C++
compiler: orbacusidl --impl Display2.idl where
orbacusidl is an alias in our .tcshrc file that
is set to the proper location of the orbacus idl compiler.
This generates the files:
-
Display2.h: the header file for the interface
- Display2_skel.h: the header file for the server skeletons
- Display2.cpp: the code for the interface
- Display2_skel.cpp: the code for the server skeletons
- Display2_impl.h: the header for the server code we need to implement
This has generated code that we sometimes need
to add to.
- Display2_impl.cpp: the generated server code for our implementations of
interface methods. We generally need to add to these
code fragments.
We move the Display2_impl.h and Display2_impl.cpp to the
App subdirectory where we will do our personal additions to the
implementation code and then we compile the basic code that is left using the
makefile MakeLibraryShared. This generates the library
libMyTimeFactory.so.
5.1.2 The Implementation Header File:
Let's now look at the file Display2_impl.h: the full code is as
follows:
Display2_impl.h
1 #ifndef ___Display2_impl_h__
2 #define ___Display2_impl_h__
3
4 #include <Display2_skel.h>
5
6 //
7 // IDL:Display2:1.0
8 //
9 namespace Display2
10 {
11
12 //
13 // IDL:Display2/MyTime:1.0
14 //
15 class MyTime_impl : virtual public POA_Display2::MyTime,
16 virtual public PortableServer::RefCountServantBase
17 {
18 MyTime_impl(const MyTime_impl&);
19 void operator=(const MyTime_impl&);
20
21 PortableServer::POA_var poa_;
22
23 public:
24
25 MyTime_impl(PortableServer::POA_ptr);
26 ~MyTime_impl();
27
28 virtual PortableServer::POA_ptr _default_POA();
29
30 //
31 // IDL:Display2/MyTime/getgmt:1.0
32 //
33 virtual Display2::TimeOfDay getgmt()
34 throw(CORBA::SystemException);
35 };
36
37 //
38 // IDL:Display2/MyTimeFactory:1.0
39 //
40 class MyTimeFactory_impl : virtual public POA_Display2::MyTimeFactory,
41 virtual public PortableServer::RefCountServantBase
42 {
43 MyTimeFactory_impl(const MyTimeFactory_impl&);
44 void operator=(const MyTimeFactory_impl&);
45
46 PortableServer::POA_var poa_;
47
48 public:
49
50 MyTimeFactory_impl(PortableServer::POA_ptr);
51 ~MyTimeFactory_impl();
52
53 virtual PortableServer::POA_ptr _default_POA();
54
55 //
56 // IDL:Display2/MyTimeFactory/CreateMyTime:1.0
57 //
58 virtual Display2::MyTime_ptr CreateMyTime()
59 throw(CORBA::SystemException);
60 };
61
62 } // End of namespace Display2
63
64 #endif
syntax highlighted by Code2HTML, v. 0.8.8b
Let's examine this more closely: we implement the class
class MyTime_impl by deriving it from
virtual public POA_Display2::MyTime and from
virtual public PortableServer::RefCountServantBase.
The second derivation sets up reference counting in our class.
Here is the class header:
frag2.cpp
1 class MyTime_impl : virtual public POA_Display2::MyTime,
2 virtual public PortableServer::RefCountServantBase
3 {
4 MyTime_impl(const MyTime_impl&);
5 void operator=(const MyTime_impl&);
6
7 PortableServer::POA_var poa_;
8
9 public:
10
11 MyTime_impl(PortableServer::POA_ptr);
12 ~MyTime_impl();
13
14 virtual PortableServer::POA_ptr _default_POA();
15
16 //
17 // IDL:Display2/MyTime/getgmt:1.0
18 //
19 virtual Display2::TimeOfDay getgmt()
20 throw(CORBA::SystemException);
21 };
syntax highlighted by Code2HTML, v. 0.8.8b
Note, we are given
-
A copy constructor: MyTime_impl(const MyTime_impl&)
- The Overloaded equal: void operator=(const MyTime_impl&)
- A class variable: PortableServer::POA_var poa_
- A Constructor: MyTime_impl(PortableServer::POA_ptr)
- A Destructor ~MyTime_impl()
- A get the poa method virtual PortableServer::POA_ptr _default_POA()
- Our getgmt method virtual Display2::TimeOfDay getgmt()
For this simple interface, we only need to add the code for the
getgmt method. Later we will see we will add variables to the
header file <something>_impl.h and to the implementation file
<something>_imp.cpp for local data structure storage.
The class for the MyTimeFactory is set up in a very
similar manner. The method we need to implement is the
frag3.cpp
1 virtual Display2::MyTime_ptr CreateMyTime()
2 throw(CORBA::SystemException);
3
syntax highlighted by Code2HTML, v. 0.8.8b
5.1.3 The New Implementation Files:
Now the implementations are very straightforward:
First, we implement the
Display2::TimeOfDay Display2::MyTime_impl::getgmt() method
like so:
frag4.cpp
1 //
2 // IDL:Display2/MyTime/getgmt:1.0
3 //
4 Display2::TimeOfDay
5 Display2::MyTime_impl::getgmt()
6 throw(CORBA::SystemException)
7 {
8 Display2::TimeOfDay tod;
9
10 time_t time_now = time(0);
11 struct tm *time_p = gmtime(&time_now);
12
13 tod.hour = time_p->tm_hour;
14 tod.minute = time_p->tm_min;
15 tod.second = time_p->tm_sec;
16
17 return tod;
18 }
syntax highlighted by Code2HTML, v. 0.8.8b
We then must implement the creation method for the factory
Display2::MyTime_ptr Display2::MyTimeFactory_impl::CreateMyTime().
We have never done this one before. Here is the code without comments:
frag5.cpp
1 //
2 // IDL:Display2/MyTimeFactory/CreateMyTime:1.0
3 //
4 Display2::MyTime_ptr
5 Display2::MyTimeFactory_impl::CreateMyTime()
6 throw(CORBA::SystemException)
7 {
8 Display2::MyTime_impl *MyTimeimpl = new Display2::MyTime_impl(poa_);
9 return MyTimeimpl->_this();
10 }
syntax highlighted by Code2HTML, v. 0.8.8b
This is a typical simple creation method for a factory. Let's comment
on these lines of code:
The full implementation code is thus:
Display2_impl.cpp
1 #include <OB/CORBA.h>
2 #include <Display2_impl.h>
3
4 //
5 // IDL:Display2:1.0
6 //
7
8 //
9 // IDL:Display2/MyTime:1.0
10 //
11 Display2::MyTime_impl::MyTime_impl(PortableServer::POA_ptr poa)
12 : poa_(PortableServer::POA::_duplicate(poa))
13 {
14 }
15
16 Display2::MyTime_impl::~MyTime_impl()
17 {
18 }
19
20 PortableServer::POA_ptr
21 Display2::MyTime_impl::_default_POA()
22 {
23 return PortableServer::POA::_duplicate(poa_);
24 }
25
26 //
27 // IDL:Display2/MyTime/getgmt:1.0
28 //
29 Display2::TimeOfDay
30 Display2::MyTime_impl::getgmt()
31 throw(CORBA::SystemException)
32 {
33 Display2::TimeOfDay tod;
34
35 time_t time_now = time(0);
36 struct tm *time_p = gmtime(&time_now);
37
38 tod.hour = time_p->tm_hour;
39 tod.minute = time_p->tm_min;
40 tod.second = time_p->tm_sec;
41
42 return tod;
43 }
44
45 //
46 // IDL:Display2/MyTimeFactory:1.0
47 //
48 Display2::MyTimeFactory_impl::MyTimeFactory_impl(PortableServer::POA_ptr poa)
49 : poa_(PortableServer::POA::_duplicate(poa))
50 {
51 }
52
53 Display2::MyTimeFactory_impl::~MyTimeFactory_impl()
54 {
55 }
56
57 PortableServer::POA_ptr
58 Display2::MyTimeFactory_impl::_default_POA()
59 {
60 return PortableServer::POA::_duplicate(poa_);
61 }
62
63 //
64 // IDL:Display2/MyTimeFactory/CreateMyTime:1.0
65 //
66 Display2::MyTime_ptr
67 Display2::MyTimeFactory_impl::CreateMyTime()
68 throw(CORBA::SystemException)
69 {
70 // Create an object
71 cout << "MyTimeFactory:: create a MyTime Object" << endl;
72
73 cout << "create Display2::MyTime_impl *MyTimeimpl" << endl;
74 cout << " = new Display2::MyTime_impl(poa_)" << endl;
75 Display2::MyTime_impl *MyTimeimpl = new Display2::MyTime_impl(poa_);
76
77 cout << "return mytime object" << endl;
78 cout << " call return MyTimeimpl->_this();" << endl;
79 return MyTimeimpl->_this();
80 }
syntax highlighted by Code2HTML, v. 0.8.8b
5.1.4 The New Server:
The general layout of the server code is as before: what is new is the
binding of the factory object to our name structure. The relevant code
to do this is as follows:
frag6.cpp
1 // Create an object
2 cout << "create a MyTimeFactory Object" << endl;
3 Display2::MyTimeFactory_impl *MyTimeFactoryimpl
4 = new Display2::MyTimeFactory_impl(rootPoa);
5 PortableServer::ServantBase_var servant = MyTimeFactoryimpl;
6 Display2::MyTimeFactory_var mytimefactory
7 = MyTimeFactoryimpl->_this();
8
9 cout << "initialize the name of our object to "
10 << "app2.devices" << argv[1] << endl;
11
12 cout << "create app2 context " << endl;
13 CosNaming::NamingContext_var app2;
14 CosNaming::Name name;
15 name.length(1);
16 name[0].id = CORBA::string_dup("app2");
17 name[0].kind = CORBA::string_dup("");
18 cout << "bind context for app2" << endl;
19 app2 = inc->bind_new_context(name);
20
21 CosNaming::NamingContext_var devices;
22 name[0].id = CORBA::string_dup("devices");
23 name[0].kind = CORBA::string_dup("");
24 cout << "bind context for devices" << endl;
25 devices = app2->bind_new_context(name);
26
27 cout << "bind object" << endl;
28 name[0].id = CORBA::string_dup(argv[1]);
29 name[0].kind = CORBA::string_dup("");
30 cout << "bind mytimefactory object" << endl;
31 devices->bind(name,mytimefactory);
syntax highlighted by Code2HTML, v. 0.8.8b
Let's look at this line by line:
-
First, we create the factory object
Display2::MyTimeFactory_impl *MyTimeFactoryimpl on the heap
as usual.
Display2::MyTimeFactory_impl *MyTimeFactoryimpl
= new Display2::MyTimeFactory_impl(rootPoa);
- Next we assign a servant object. We are not sure
why we do this! Can anyone help?
PortableServer::ServantBase_var servant = MyTimeFactoryimpl;
- We construct the needed factory object:
Display2::MyTimeFactory_var mytimefactory
= MyTimeFactoryimpl->_this();
- We set up the naming tree for our object.
Just for a nice example, we have decided to name this
object as app2 -> devices -> Dragon
where Dragon is the name we enter on our command line
when we start the server as argv[1]. This is a lot like
a path name. We need to initialize CosNaming::Name name
objects which have fields
-
name.length -- if name.length was N, then we
would have to fill in name[p].id and name[p].kind
for the choices of p from 0 to N-1.
- name[].id and name[].kind for the needed
index choices.
So app2 is a CosNaming::NamingContext_var app2
and it is initialized with a CosNaming::Name name
we set up like this:
CosNaming::NamingContext_var app2;
CosNaming::Name name;
name.length(1);
name[0].id = CORBA::string_dup("app2");
name[0].kind = CORBA::string_dup("");
- We then bind this "name" to the context app2 like so:
app2 = inc->bind_new_context(name);
- We then do the same for the context devices:
CosNaming::NamingContext_var devices;
name[0].id = CORBA::string_dup("devices");
devices = app2->bind_new_context(name);
name[0].id = CORBA::string_dup(argv[1]);
devices->bind(name,mytimefactory);
The full server code is as follows:
server2.cpp
1 #include <stdio.h>
2 #include <time.h>
3 #include <iostream.h>
4 #include <fstream.h>
5 #include "mystring.h"
6 #include "charvec1.h"
7 #include <OB/CORBA.h>
8 #include <OB/CosNaming.h>
9 #include "Display2_skel.h"
10 #include "Display2_impl.h"
11 #include "utility.h"
12
13 #ifdef HAVE_FSTREAM
14 # include <fstream>
15 #else
16 # include <fstream.h>
17 #endif
18
19 #ifdef HAVE_STD_IOSTREAM
20 using namespace std;
21 #endif
22
23 int
24 run(CORBA::ORB_ptr orb,int argc, char *argv[])
25 {
26 char *Object_File = "object-ior";
27 ofstream ifp;
28 CORBA::Object_var Temp;
29
30 // Get reference to Root POA.
31 cout << "In run" << endl;
32 cout << "resolve initial refs " << endl;
33 CORBA::Object_var poaObj = orb->resolve_initial_references("RootPOA");
34
35 cout << " set rootPoa" << endl;
36 PortableServer::POA_var rootPoa
37 = PortableServer::POA::_narrow(poaObj);
38
39 // Get Reference to POA manager
40 cout << "get reference to poa manager" << endl;
41 PortableServer::POAManager_var manager = rootPoa->the_POAManager();
42
43 cout << "activate poa manager " << endl;
44 manager->activate();
45
46 cout << "get reference to initial naming context" << endl;
47 CORBA::Object_var nsobj;
48 nsobj = orb->resolve_initial_references("NameService");
49
50 cout << "narrow name context" << endl;
51 CosNaming::NamingContext_var inc;
52 inc = CosNaming::NamingContext::_narrow(nsobj);
53
54 // Create an object
55 cout << "create a MyTimeFactory Object" << endl;
56 Display2::MyTimeFactory_impl *MyTimeFactoryimpl
57 = new Display2::MyTimeFactory_impl(rootPoa);
58 PortableServer::ServantBase_var servant = MyTimeFactoryimpl;
59 Display2::MyTimeFactory_var mytimefactory
60 = MyTimeFactoryimpl->_this();
61
62 cout << "initialize the name of our object to "
63 << "app2.devices" << argv[1] << endl;
64
65 cout << "create app2 context " << endl;
66 CosNaming::NamingContext_var app2;
67 CosNaming::Name name;
68 name.length(1);
69 name[0].id = CORBA::string_dup("app2");
70 name[0].kind = CORBA::string_dup("");
71 cout << "bind context for app2" << endl;
72 app2 = inc->bind_new_context(name);
73
74 CosNaming::NamingContext_var devices;
75 name[0].id = CORBA::string_dup("devices");
76 name[0].kind = CORBA::string_dup("");
77 cout << "bind context for devices" << endl;
78 devices = app2->bind_new_context(name);
79
80 cout << "bind object" << endl;
81 name[0].id = CORBA::string_dup(argv[1]);
82 name[0].kind = CORBA::string_dup("");
83 cout << "bind mytimefactory object" << endl;
84 devices->bind(name,mytimefactory);
85
86 // Accept requests
87 cout << "run orb" << endl;
88 orb->run();
89
90 return EXIT_SUCCESS;
91 }
92
93 int main(int argc, char* argv[])
94 {
95 int status = 0;
96 CORBA::ORB_var orb;
97
98 int check_ior = 1;
99 int dummy_argc;
100 char *dummy_argv[10];
101
102 //======================================================//
103 // For our Orbacus server we start up with
104 // ./server2: this is argv[0]
105 // option 1 <name of our server object>: this is argv[1]
106 // option 2 -OAbind 127.0.0.1: this is argv[2]
107 // and argv[3]
108 // option 2 -OAhost shortstuff: this is argv[4]
109 // and argv[5]
110 // option 3 -ORBtrace_connections 1 this is argv[6]
111 // and argv[7]
112 //======================================================//
113 if(argc!=8){
114 cout << "start server as ./server2 opt1 opt2 opt3 opt4" << endl;
115 cout << " where opt1 = <name of our served object>" << endl;
116 cout << " where opt2 = -OAbind <ip address of host> " << endl;
117 cout << " where opt3 = -OAhost <host name> " << endl;
118 cout << " where opt4 = -ORBtrace_connections 1 " << endl;
119 exit(-1);
120 }
121 else{
122 for(int p=0;p<argc;++p)
123 cout << "argv[" << p << "] = " << argv[p] << endl;
124 }
125
126 cout << " get name server IOR from file" << endl;
127 cout << " form opt 4 = -ORBnaming <IOR string from file>" << endl;
128 cout << " and form as argument to pass to ORB_init" << endl;
129
130 dummy_argc = argc+2;
131
132 STRING s0(argv[0]);
133 s0.getLabel(&(dummy_argv[0])); //this is ./server2
134
135 STRING s1(argv[1]);
136 s1.getLabel(&(dummy_argv[1])); //this is <name of our served object>
137
138 STRING s2(argv[2]);
139 s2.getLabel(&(dummy_argv[2])); //this is opt 1 -OAbind
140 STRING s3(argv[3]);
141 s3.getLabel(&(dummy_argv[3])); //this is opt 1 address
142
143 STRING s4(argv[4]);
144 s4.getLabel(&(dummy_argv[4])); //this is opt 2 -OAhost
145 STRING s5(argv[5]);
146 s5.getLabel(&(dummy_argv[5])); //this is opt 2 host name
147
148 STRING s6(argv[6]);
149 s6.getLabel(&(dummy_argv[6])); //this is opt 3 -ORBtrace_connections
150 STRING s7(argv[7]);
151 s7.getLabel(&(dummy_argv[7])); //this is opt 3 level <n=1,2,...>
152
153 STRING s8("-ORBnaming");
154 s8.getLabel(&(dummy_argv[8])); //this is -ORBnaming
155
156 STRING NameServerIOR = getIOR();
157 NameServerIOR.getLabel(&(dummy_argv[9]));
158
159 if(check_ior==1){
160 for(int p=0;p<dummy_argc;++p)
161 cout << "dummy_argv[" << p << "] = " << dummy_argv[p] << endl;
162 }
163
164 try{
165 //initialize orb
166 cout << "Initialize orb" << endl;
167 orb = CORBA::ORB_init(dummy_argc,dummy_argv);
168
169 cout << "Call run" << endl;
170 status = run(orb,argc,argv);
171 }
172 catch(const CORBA::Exception& ex){
173 cerr << ex << endl;
174 status = EXIT_FAILURE;
175 }
176 if(!CORBA::is_nil(orb)){
177 try{
178 orb -> destroy();
179 }
180 catch(const CORBA::Exception& ex){
181 cerr << ex << endl;
182 status = EXIT_FAILURE;
183 }
184 }
185 return status;
186 }
syntax highlighted by Code2HTML, v. 0.8.8b
5.1.5 The New Client:
In the new client, much is as we have done before. What is new
is the finding of our served factory object and then it's use.
The relevant code is:
frag7.cpp
1 CORBA::Object_var Temp;
2 CORBA::Object_var nsobj;
3 nsobj = orb->resolve_initial_references("NameService");
4
5 CosNaming::NamingContext_var inc;
6 inc = CosNaming::NamingContext::_narrow(nsobj);
7
8 CosNaming::Name name;
9 name.length(3);
10 name[0].id = CORBA::string_dup("app2");
11 name[0].kind = CORBA::string_dup("");
12 name[1].id = CORBA::string_dup("devices");
13 name[1].kind = CORBA::string_dup("");
14 name[2].id = CORBA::string_dup(argv[1]);
15 name[2].kind = CORBA::string_dup("");
16
17 try{
18 cout << "resolve new context" << endl;
19 Temp = inc->resolve(name);
20 }
21 catch(const CosNaming::NamingContext::NotFound&){
22 cerr << "No name for object" << endl;
23 throw 0;
24 }
25 catch(const CORBA::Exception& e){
26 cerr << "resolve failed" << e << endl;
27 throw 0;
28 }
29
30 if(CORBA::is_nil(Temp)){
31 cerr << "Nil reference for server object" << endl;
32 throw 0;
33 }
34
35 Display2::MyTimeFactory_var mytimefactory;
36 try{
37 mytimefactory = Display2::MyTimeFactory::_narrow(Temp);
38 }
39 catch(const CORBA::Exception& e){
40 cerr << "cannot narrow mytimefactory reference" << e << endl;
41 throw 0;
42 }
43 if(CORBA::is_nil(mytimefactory)){
44 cerr << "mytime reference is of wrong type" << endl;
45 throw 0;
46 }
47
48 Display2::MyTime_ptr mytime = mytimefactory->CreateMyTime();
49 Display2::TimeOfDay tod = mytime->getgmt();
50
51 cout << "Time of Day is ("
52 << tod.hour << ","
53 << tod.minute << ","
54 << tod.second << "]" << endl;
55
syntax highlighted by Code2HTML, v. 0.8.8b
Let's look at this code more closely:
-
First we find the initial reference to the
Name Server object. This returns as a
CORBA::Object_var.
CORBA::Object_var nsobj;
nsobj = orb->resolve_initial_references("NameService");
- We narrow this object to an object of
type CosNaming::NamingContext_var inc:
CosNaming::NamingContext_var inc;
inc = CosNaming::NamingContext::_narrow(nsobj);
- We set up a CosNaming::Name name
data structure to hold our "path"
app2->devices->"argv[1]". This of course
means that we as a client must "know" this full
"name" -- this is a problem we will need to think
about. Note this name structure has a length of 3.
CosNaming::Name name;
name.length(3);
name[0].id = CORBA::string_dup("app2");
name[0].kind = CORBA::string_dup("");
name[1].id = CORBA::string_dup("devices");
name[1].kind = CORBA::string_dup("");
name[2].id = CORBA::string_dup(argv[1]);
name[2].kind = CORBA::string_dup("");
- We then try to resolve this name to an
object using the Name Server:
CORBA_Object_var Temp;
Temp = inc->resolve(name);
- Next, we narrow the returned object to
a factory object Display2::MyTimeFactory_var mytimefactory:
Display2::MyTimeFactory_var mytimefactory;
mytimefactory = Display2::MyTimeFactory::_narrow(Temp);
- Then we create a Display2::MyTime_ptr mytime object
using the resolved object reference;
Display2::MyTime_ptr mytime = mytimefactory->CreateMyTime();
- Then we use this object to find the time of day:
Display2::TimeOfDay tod = mytime->getgmt();
Now, we actually would not use a simple statement like
Temp = inc->resolve(name);. Instead, we would
use try and catch clauses to help us exit gracefully
in case of problems. So the code would look like this:
frag8.cpp
1 try{
2 cout << "resolve new context" << endl;
3 Temp = inc->resolve(name);
4 }
5 catch(const CosNaming::NamingContext::NotFound&){
6 cerr << "No name for object" << endl;
7 throw 0;
8 }
9 catch(const CORBA::Exception& e){
10 cerr << "resolve failed" << e << endl;
11 throw 0;
12 }
13
14 if(CORBA::is_nil(Temp)){
15 cerr << "Nil reference for server object" << endl;
16 throw 0;
17 }
syntax highlighted by Code2HTML, v. 0.8.8b
The full client code contains some of the try-catch clauses we
have mentioned. The full code is as follows:
client2.cpp
1 #include <stdio.h>
2 #include <time.h>
3 #include <iostream.h>
4 #include <fstream.h>
5 #include "mystring.h"
6 #include "charvec1.h"
7 #include <OB/CORBA.h>
8 #include <OB/CosNaming.h>
9 #include "Display2.h"
10 #include "Display2_impl.h"
11 #include "utility.h"
12
13 int run(CORBA::ORB_ptr orb, int argc, char* argv[])
14 {
15
16 CORBA::Object_var Temp;
17
18 cout << "get reference to initial naming context" << endl;
19 CORBA::Object_var nsobj;
20 nsobj = orb->resolve_initial_references("NameService");
21
22 cout << "narrow name context" << endl;
23 CosNaming::NamingContext_var inc;
24 inc = CosNaming::NamingContext::_narrow(nsobj);
25
26 cout << "initialize the name of our object to look for to "
27 << argv[1] << endl;
28 CosNaming::Name name;
29 name.length(3);
30 name[0].id = CORBA::string_dup("app2");
31 name[0].kind = CORBA::string_dup("");
32 name[1].id = CORBA::string_dup("devices");
33 name[1].kind = CORBA::string_dup("");
34 name[2].id = CORBA::string_dup(argv[1]);
35 name[2].kind = CORBA::string_dup("");
36
37 cout << "resolve name" << endl;
38 try{
39 cout << "resolve new context" << endl;
40 Temp = inc->resolve(name);
41 }
42 catch(const CosNaming::NamingContext::NotFound&){
43 cerr << "No name for object" << endl;
44 throw 0;
45 }
46 catch(const CORBA::Exception& e){
47 cerr << "resolve failed" << e << endl;
48 throw 0;
49 }
50
51 if(CORBA::is_nil(Temp)){
52 cerr << "Nil reference for server object" << endl;
53 throw 0;
54 }
55
56 cout << "narrow to mytimefactory" << endl;
57 Display2::MyTimeFactory_var mytimefactory;
58 try{
59 mytimefactory = Display2::MyTimeFactory::_narrow(Temp);
60 }
61 catch(const CORBA::Exception& e){
62 cerr << "cannot narrow mytimefactory reference" << e << endl;
63 throw 0;
64 }
65 if(CORBA::is_nil(mytimefactory)){
66 cerr << "mytime reference is of wrong type" << endl;
67 throw 0;
68 }
69
70 cout << "use mytimefactory reference" << endl;
71 cout << "create a MyTime Object:" << endl;
72 Display2::MyTime_ptr mytime = mytimefactory->CreateMyTime();
73 Display2::TimeOfDay tod = mytime->getgmt();
74
75 cout << "Time of Day is ("
76 << tod.hour << ","
77 << tod.minute << ","
78 << tod.second << "]" << endl;
79
80 return 0;
81 }
82
83 int main(int argc, char* argv[])
84 {
85 int status = 0;
86 CORBA::ORB_var orb;
87
88 int check_ior = 1;
89 int dummy_argc;
90 char *dummy_argv[10];
91
92 //======================================================//
93 // For our Orbacus client we start up with
94 // ./client2: this is argv[0]
95 // option 1 <name of our served object>: this is argv[1]
96 // option 2 -OAbind 127.0.0.1: this is argv[2]
97 // and argv[3]
98 // option 3 -OAhost shortstuff: this is argv[4]
99 // and argv[5]
100 // option 4 -ORBtrace_connections 1 this is argv[6]
101 // and argv[7]
102 //======================================================//
103 if(argc!=8){
104 cout << "start client as ./client2 opt1 opt2 opt3 opt4" << endl;
105 cout << " where opt1 = <name of our served object>" << endl;
106 cout << " where opt2 = -OAbind <ip address of host> " << endl;
107 cout << " where opt3 = -OAhost <host name> " << endl;
108 cout << " where opt4 = -ORBtrace_connections 1 " << endl;
109 exit(-1);
110 }
111 else{
112 for(int p=0;p<argc;++p)
113 cout << "argv[" << p << "] = " << argv[p] << endl;
114 }
115
116 cout << " get name server IOR from file" << endl;
117 cout << " form opt 4 = -ORBnaming <IOR string from file>" << endl;
118 cout << " and form as argument to pass to ORB_init" << endl;
119
120 dummy_argc = argc+2;
121
122 STRING s0(argv[0]);
123 s0.getLabel(&(dummy_argv[0])); //this is ./server2
124
125 STRING s1(argv[1]);
126 s1.getLabel(&(dummy_argv[1])); //this is <name of our served object>
127
128 STRING s2(argv[2]);
129 s2.getLabel(&(dummy_argv[2])); //this is opt 1 -OAbind
130 STRING s3(argv[3]);
131 s3.getLabel(&(dummy_argv[3])); //this is opt 1 address
132
133 STRING s4(argv[4]);
134 s4.getLabel(&(dummy_argv[4])); //this is opt 2 -OAhost
135 STRING s5(argv[5]);
136 s5.getLabel(&(dummy_argv[5])); //this is opt 2 host name
137
138 STRING s6(argv[6]);
139 s6.getLabel(&(dummy_argv[6])); //this is opt 3 -ORBtrace_connections
140 STRING s7(argv[7]);
141 s7.getLabel(&(dummy_argv[7])); //this is opt 3 level <n=1,2,...>
142
143 STRING s8("-ORBnaming");
144 s8.getLabel(&(dummy_argv[8])); //this is -ORBnaming
145
146 STRING NameServerIOR = getIOR();
147 NameServerIOR.getLabel(&(dummy_argv[9]));
148
149 if(check_ior==1){
150 for(int p=0;p<dummy_argc;++p)
151 cout << "dummy_argv[" << p << "] = " << dummy_argv[p] << endl;
152 }
153
154
155 try{
156 //initialize orb
157 cout << "Initialize orb" << endl;
158 orb = CORBA::ORB_init(dummy_argc,dummy_argv);
159
160 cout << "Call run" << endl;
161 status = run(orb,argc,argv);
162 }
163 catch(const CORBA::Exception& ex){
164 cerr << ex << endl;
165 status = EXIT_FAILURE;
166 }
167 if(!CORBA::is_nil(orb)){
168 try{
169 orb -> destroy();
170 }
171 catch(const CORBA::Exception& ex){
172 cerr << ex << endl;
173 status = EXIT_FAILURE;
174 }
175 }
176 return status;
177 }
syntax highlighted by Code2HTML, v. 0.8.8b
5.1.6 The RunTime Results:
First, we start the name server:
[petersj@shortstuff App]$ rm name-service-ior
rm: remove `name-service-ior'? y
[petersj@shortstuff App]$
/home/petersj/orbacus/bin/nameserv -i > name-service-ior&
[3] 647
Then we start the server:
[petersj@shortstuff App]$
./server2 Dragon -OAbind 192.168.0.1
-OAhost shortstuff -ORBtrace_connections 1&
[5] 947
[petersj@shortstuff App]$ argv[0] = ./server2
argv[1] = Dragon
argv[2] = -OAbind
argv[3] = 192.168.0.1
argv[4] = -OAhost
argv[5] = shortstuff
argv[6] = -ORBtrace_connections
argv[7] = 1
get name server IOR from file
form opt 4 = -ORBnaming <IOR string from file>
and form as argument to pass to ORB_init
Get the Naming Service IOR from the file
File is available: Get the IOR string
reading IOR from file
IOR:011706082a00000049444c3a6f6f632e636f6d2f436f73
4e616d696e672f4f424e616d696e67436f6e746578743a312e
3000060801000000000000007c000000010102400c00000031
39322e3136382e302e31001304894028000000abacab305f52
6f6f74504f4100526f6f74436f6e74657874504f4100004e61
6d655365727669636501000000010000002c000000014e8940
01000100020000000100010520000100090101000400000000
010100010001000100010520000100
strip off ending carriage return
finished reading IOR from file
dummy_argv[0] = ./server2
dummy_argv[1] = Dragon
dummy_argv[2] = -OAbind
dummy_argv[3] = 192.168.0.1
dummy_argv[4] = -OAhost
dummy_argv[5] = shortstuff
dummy_argv[6] = -ORBtrace_connections
dummy_argv[7] = 1
dummy_argv[8] = -ORBnaming
dummy_argv[9] = IOR:011706082a00000049444c3a6f6f632
e636f6d2f436f734e616d696e672f4f424e616d696e67436f6e
746578743a312e3000060801000000000000007c00000001010
2400c0000003139322e3136382e302e31001304894028000000
abacab305f526f6f74504f4100526f6f74436f6e74657874504
f4100004e616d655365727669636501000000010000002c0000
00014e894001000100020000000100010520000100090101000
400000000010100010001000100010520000100
Initialize orb
Call run
In run
resolve initial refs
[ incoming: accepting connections
id: TAG_IIOP
local address: 192.168.0.1:1044
hosts: shortstuff ]
set rootPoa
get reference to poa manager
activate poa manager
get reference to initial naming context
narrow name context
[ outgoing: trying to establish connection
timeout: none
id: TAG_IIOP
remote address: 192.168.0.1:1043 ]
[ outgoing: new connection
id: TAG_IIOP
local address: 192.168.0.1:1045
remote address: 192.168.0.1:1043 ]
create a MyTimeFactory Object
initialize the name of our object to app2.devicesDragon
create app2 context
bind context for app2
bind context for devices
bind object
bind mytimefactory object
run orb
Finally, we start the client:
[petersj@shortstuff App]$
./client2 Dragon -OAbind 192.168.0.1
-OAhost shortstuff -ORBtrace_connections 1
argv[0] = ./client2
argv[1] = Dragon
argv[2] = -OAbind
argv[3] = 192.168.0.1
argv[4] = -OAhost
argv[5] = shortstuff
argv[6] = -ORBtrace_connections
argv[7] = 1
get name server IOR from file
form opt 4 = -ORBnaming <IOR string from file>
and form as argument to pass to ORB_init
Get the Naming Service IOR from the file
File is available: Get the IOR string
reading IOR from file
IOR:011706082a00000049444c3a6f6f632e636f6d2f436f734
e616d696e672f4f424e616d696e67436f6e746578743a312e30
00060801000000000000007c000000010102400c00000031393
22e3136382e302e31001304894028000000abacab305f526f6f
74504f4100526f6f74436f6e74657874504f4100004e616d655
365727669636501000000010000002c000000014e8940010001
000200000001000105200001000901010004000000000101000
10001000100010520000100
strip off ending carriage return
finished reading IOR from file
dummy_argv[0] = ./client2
dummy_argv[1] = Dragon
dummy_argv[2] = -OAbind
dummy_argv[3] = 192.168.0.1
dummy_argv[4] = -OAhost
dummy_argv[5] = shortstuff
dummy_argv[6] = -ORBtrace_connections
dummy_argv[7] = 1
dummy_argv[8] = -ORBnaming
dummy_argv[9] = IOR:011706082a00000049444c3a6f6f632e
636f6d2f436f734e616d696e672f4f424e616d696e67436f6e74
6578743a312e3000060801000000000000007c00000001010240
0c0000003139322e3136382e302e31001304894028000000abac
ab305f526f6f74504f4100526f6f74436f6e74657874504f4100
004e616d655365727669636501000000010000002c000000014e
8940010001000200000001000105200001000901010004000000
00010100010001000100010520000100
Initialize orb
Call run
get reference to initial naming context
narrow name context
[ outgoing: trying to establish connection
timeout: none
id: TAG_IIOP
remote address: 192.168.0.1:1043 ]
[ outgoing: new connection
id: TAG_IIOP
local address: 192.168.0.1:1046
remote address: 192.168.0.1:1043 ]
initialize the name of our object to look for to Dragon
resolve name
resolve new context
narrow to mytimefactory
use mytimefactory reference
create a MyTime Object:
[ outgoing: trying to establish connection
timeout: none
id: TAG_IIOP
remote address: 192.168.0.1:1044 ]
[ outgoing: new connection
id: TAG_IIOP
local address: 192.168.0.1:1047
remote address: 192.168.0.1:1044 ]
[ incoming: new connection
id: TAG_IIOP
local address: 192.168.0.1:1044
remote address: 192.168.0.1:1047 ]
MyTimeFactory:: create a MyTime Object
create Display2::MyTime_impl *MyTimeimpl
= new Display2::MyTime_impl(poa_)
set PortableServer::ServantBase_var result to
MyTimeimpl;
get servant poa
call PortableServer::POA_var poa = MyTimeimpl->_default_POA();
return mytime object
call return MyTimeimpl->_this();
Time of Day is (18,26,15]
[ outgoing: closing connection
id: TAG_IIOP
local address: 192.168.0.1:1046
remote address: 192.168.0.1:1043 ]
[ incoming: closing connection
id: TAG_IIOP
local address: 192.168.0.1:1044
remote address: 192.168.0.1:1047 ]
[ outgoing: closing connection
id: TAG_IIOP
local address: 192.168.0.1:1047
remote address: 192.168.0.1:1044 ]
[petersj@shortstuff App]$
5.2 A More Sophisticated Factory Example:
Let's now create a more complicated factory example using the
Triangle, Rectangle and so forth interfaces.
We will now place these in a new module called Polygons.
Much of what we have said in the previous section is still valid,
so we will move through this quickly.
5.2.1 The New Interface: Polygons.idl:
We now add the familiar polygon objects to our IDL.
The full interface description is this:
Polygons.idl
1 module Polygons{
2 struct Position{
3 float x;
4 float y;
5 };
6 typedef sequence<Position,5> RectanglePosition;
7 typedef sequence<Position,4> TrianglePosition;
8 struct TimeOfDay{
9 short hour;
10 short minute;
11 short second;
12 };
13 interface MyTime{
14 TimeOfDay getgmt();
15 };
16 interface Circle{
17 void SetPosition(in MyTime t);
18 void FindPosition(out Position P);
19 void SetRadius(in MyTime t);
20 void FindRadius(out float r);
21 void Translate(in Position Offset);
22 void Rotate(in float angle);
23 };
24 interface Triangle{
25 void SetPosition(in MyTime t);
26 void FindPosition(out TrianglePosition P);
27 void Translate(in Position Offset);
28 void Rotate(in float angle);
29 };
30 interface Rectangle{
31 void SetPosition(in MyTime t);
32 void FindPosition(out RectanglePosition P);
33 void Translate(in Position Offset);
34 void Rotate(in float angle);
35 };
36 interface PolygonFactory{
37 Circle CreateCircle();
38 Rectangle CreateRectangle();
39 Triangle CreateTriangle();
40 MyTime CreateMyTime();
41 };
42 };
syntax highlighted by Code2HTML, v. 0.8.8b
5.2.2 The New Implementation Header File:
The Orbacus IDL compiler will generate our basic implementation
header and code files for us. The header looks very familiar:
Polygons_impl.h
1 #ifndef ___Polygons_impl_h__
2 #define ___Polygons_impl_h__
3
4 #include <Polygons_skel.h>
5
6 //
7 // IDL:Polygons:1.0
8 //
9 namespace Polygons
10 {
11
12 //
13 // IDL:Polygons/MyTime:1.0
14 //
15 class MyTime_impl : virtual public POA_Polygons::MyTime,
16 virtual public PortableServer::RefCountServantBase
17 {
18 MyTime_impl(const MyTime_impl&);
19 void operator=(const MyTime_impl&);
20
21 PortableServer::POA_var poa_;
22
23 public:
24
25 MyTime_impl(PortableServer::POA_ptr);
26 ~MyTime_impl();
27
28 virtual PortableServer::POA_ptr _default_POA();
29
30 //
31 // IDL:Polygons/MyTime/getgmt:1.0
32 //
33 virtual Polygons::TimeOfDay getgmt()
34 throw(CORBA::SystemException);
35 };
36
37 //
38 // IDL:Polygons/Circle:1.0
39 //
40 class Circle_impl : virtual public POA_Polygons::Circle,
41 virtual public PortableServer::RefCountServantBase
42 {
43 Circle_impl(const Circle_impl&);
44 void operator=(const Circle_impl&);
45
46 PortableServer::POA_var poa_;
47 Polygons::Position center;
48 CORBA::Float radius;
49
50 public:
51
52 Circle_impl(PortableServer::POA_ptr);
53 ~Circle_impl();
54
55 virtual PortableServer::POA_ptr _default_POA();
56
57 //
58 // IDL:Polygons/Circle/SetPosition:1.0
59 //
60 virtual void SetPosition(Polygons::MyTime_ptr t)
61 throw(CORBA::SystemException);
62
63 //
64 // IDL:Polygons/Circle/FindPosition:1.0
65 //
66 virtual void FindPosition(Polygons::Position_out P)
67 throw(CORBA::SystemException);
68
69 //
70 // IDL:Polygons/Circle/SetRadius:1.0
71 //
72 virtual void SetRadius(Polygons::MyTime_ptr t)
73 throw(CORBA::SystemException);
74
75 //
76 // IDL:Polygons/Circle/FindRadius:1.0
77 //
78 virtual void FindRadius(CORBA::Float_out r)
79 throw(CORBA::SystemException);
80
81 //
82 // IDL:Polygons/Circle/Translate:1.0
83 //
84 virtual void Translate(const Polygons::Position& Offset)
85 throw(CORBA::SystemException);
86
87 //
88 // IDL:Polygons/Circle/Rotate:1.0
89 //
90 virtual void Rotate(CORBA::Float angle)
91 throw(CORBA::SystemException);
92 };
93
94 //
95 // IDL:Polygons/Triangle:1.0
96 //
97 class Triangle_impl : virtual public POA_Polygons::Triangle,
98 virtual public PortableServer::RefCountServantBase
99 {
100 Triangle_impl(const Triangle_impl&);
101 void operator=(const Triangle_impl&);
102
103 PortableServer::POA_var poa_;
104 Polygons::TrianglePosition TP;
105
106 public:
107
108 Triangle_impl(PortableServer::POA_ptr);
109 ~Triangle_impl();
110
111 virtual PortableServer::POA_ptr _default_POA();
112
113 //
114 // IDL:Polygons/Triangle/SetPosition:1.0
115 //
116 virtual void SetPosition(Polygons::MyTime_ptr t)
117 throw(CORBA::SystemException);
118
119 //
120 // IDL:Polygons/Triangle/FindPosition:1.0
121 //
122 virtual void FindPosition(Polygons::TrianglePosition_out P)
123 throw(CORBA::SystemException);
124
125 //
126 // IDL:Polygons/Triangle/Translate:1.0
127 //
128 virtual void Translate(const Polygons::Position& Offset)
129 throw(CORBA::SystemException);
130
131 //
132 // IDL:Polygons/Triangle/Rotate:1.0
133 //
134 virtual void Rotate(CORBA::Float angle)
135 throw(CORBA::SystemException);
136 };
137
138 //
139 // IDL:Polygons/Rectangle:1.0
140 //
141 class Rectangle_impl : virtual public POA_Polygons::Rectangle,
142 virtual public PortableServer::RefCountServantBase
143 {
144 Rectangle_impl(const Rectangle_impl&);
145 void operator=(const Rectangle_impl&);
146
147 PortableServer::POA_var poa_;
148
149 public:
150
151 Rectangle_impl(PortableServer::POA_ptr);
152 ~Rectangle_impl();
153
154 virtual PortableServer::POA_ptr _default_POA();
155
156 //
157 // IDL:Polygons/Rectangle/SetPosition:1.0
158 //
159 virtual void SetPosition(Polygons::MyTime_ptr t)
160 throw(CORBA::SystemException);
161
162 //
163 // IDL:Polygons/Rectangle/FindPosition:1.0
164 //
165 virtual void FindPosition(Polygons::RectanglePosition_out P)
166 throw(CORBA::SystemException);
167
168 //
169 // IDL:Polygons/Rectangle/Translate:1.0
170 //
171 virtual void Translate(const Polygons::Position& Offset)
172 throw(CORBA::SystemException);
173
174 //
175 // IDL:Polygons/Rectangle/Rotate:1.0
176 //
177 virtual void Rotate(CORBA::Float angle)
178 throw(CORBA::SystemException);
179 };
180
181 //
182 // IDL:Polygons/PolygonFactory:1.0
183 //
184 class PolygonFactory_impl : virtual public POA_Polygons::PolygonFactory,
185 virtual public PortableServer::RefCountServantBase
186 {
187 PolygonFactory_impl(const PolygonFactory_impl&);
188 void operator=(const PolygonFactory_impl&);
189
190 PortableServer::POA_var poa_;
191
192 public:
193
194 PolygonFactory_impl(PortableServer::POA_ptr);
195 ~PolygonFactory_impl();
196
197 virtual PortableServer::POA_ptr _default_POA();
198
199 //
200 // IDL:Polygons/PolygonFactory/CreateCircle:1.0
201 //
202 virtual Polygons::Circle_ptr CreateCircle()
203 throw(CORBA::SystemException);
204
205 //
206 // IDL:Polygons/PolygonFactory/CreateRectangle:1.0
207 //
208 virtual Polygons::Rectangle_ptr CreateRectangle()
209 throw(CORBA::SystemException);
210
211 //
212 // IDL:Polygons/PolygonFactory/CreateTriangle:1.0
213 //
214 virtual Polygons::Triangle_ptr CreateTriangle()
215 throw(CORBA::SystemException);
216
217 //
218 // IDL:Polygons/PolygonFactory/CreateMyTime:1.0
219 //
220 virtual Polygons::MyTime_ptr CreateMyTime()
221 throw(CORBA::SystemException);
222 };
223
224 } // End of namespace Polygons
225
226 #endif
syntax highlighted by Code2HTML, v. 0.8.8b
If you look at this closely, you will see we have added some
modifications. These are as follows:
-
We modified the Circle class to add local variables:
class Circle_impl : virtual public POA_Polygons::Circle,
virtual public PortableServer::RefCountServantBase
{
Circle_impl(const Circle_impl&);
void operator=(const Circle_impl&);
PortableServer::POA_var poa_;
Polygons::Position center; // added
CORBA::Float radius; // added
...
}
- We modified the Triangle and Rectangle classes to add
local variables also: for example, in the Triangle class:
class Triangle_impl : virtual public POA_Polygons::Triangle,
virtual public PortableServer::RefCountServantBase
{
Triangle_impl(const Triangle_impl&);
void operator=(const Triangle_impl&);
PortableServer::POA_var poa_;
Polygons::TrianglePosition TP; // added
...
}
5.2.3 Modifications to the Implementation Code:
We must add things to all of our generated classes:
the MyTime classes are done as before, but the
Circle, Triangle and so forth require new things.
Let's look at these changes closely.
Changes to the Circle Class:
-
We modified the constructor for the Circle class:
Polygons::Circle_impl::Circle_impl(PortableServer::POA_ptr poa)
: poa_(PortableServer::POA::_duplicate(poa))
{
center.x = 0.0;
center.y = 0.0;
}
- SetPosition: note we set the Center structure
as usual in C++ code:
void
Polygons::Circle_impl::SetPosition(Polygons::MyTime_ptr t)
throw(CORBA::SystemException)
{
Polygons::TimeOfDay tod;
tod = t->getgmt();
if(tod.hour<12){
center.x = tod.minute;
center.y = tod.second;
}
else{
center.x = tod.minute;
center.y = tod.hour;
}
}
- FindPosition: we have an out variable here that is
a structure; so it is mapped to a reference
Polygons::Position& which we access easily:
void
Polygons::Circle_impl::FindPosition(Polygons::Position_out P)
throw(CORBA::SystemException)
{
P.x = center.x;
P.y = center.y;
}
- SetRadius: here we just set the local radius variable using
the MyTime object that is passed in.
void
Polygons::Circle_impl::SetRadius(Polygons::MyTime_ptr t)
throw(CORBA::SystemException)
{
Polygons::TimeOfDay tod;
tod = t->getgmt();
if(tod.hour<12){
radius = tod.hour;
}
else{
radius = tod.second;
}
}
- FindRadius: here we have the out variable r which
is sent in as a reference to a float:
void
Polygons::Circle_impl::FindRadius(CORBA::Float_out r)
throw(CORBA::SystemException)
{
r = radius;
}
- Translate: The input Offset is a structure
which is mapped to a reference.
void
Polygons::Circle_impl::Translate(const Polygons::Position& Offset)
throw(CORBA::SystemException)
{
center.x += Offset.x;
center.y += Offset.y;
}
Changes to the Triangle Class:
There are many changes here. Let's go through them:
- Constructor:
Polygons::Triangle_impl::Triangle_impl(PortableServer::POA_ptr poa)
: poa_(PortableServer::POA::_duplicate(poa))
{
Polygons::Position *buf = Polygons::TrianglePosition::allocbuf(4);
Polygons::TrianglePosition data(4L,buf,1);
TP = data;
}
- SetPosition:
//
// IDL:Polygons/Triangle/SetPosition:1.0
//
void
Polygons::Triangle_impl::SetPosition(Polygons::MyTime_ptr t)
throw(CORBA::SystemException)
{
Polygons::TimeOfDay tod;
tod = t->getgmt();
if(tod.hour<12){
TP[0].x = tod.minute;
TP[0].y = tod.second;
TP[1].x = TP[0].x+20.0;
TP[1].y = TP[0].y;
TP[2].x = TP[1].x;
TP[2].y =TP[0].y + 20.0;
TP[3].x = TP[0].x;
TP[3].y = TP[0].y;
}
else{
TP[0].x = tod.minute;
TP[0].y = tod.hour;
TP[1].x = TP[0].x+20.0;
TP[1].y = TP[0].y;
TP[2].x = TP[1].x;
TP[2].y = TP[0].y + 20.0;
TP[3].x = TP[0].x;
TP[3].y = TP[0].y;
}
}
- FindPosition
//
// IDL:Polygons/Triangle/FindPosition:1.0
//
void
Polygons::Triangle_impl::FindPosition(Polygons::TrianglePosition_out P)
throw(CORBA::SystemException)
{
P = new Polygons::TrianglePosition;
Polygons::Position *buf = Polygons::TrianglePosition::allocbuf(4);
Polygons::TrianglePosition Data(4L,buf,1);
*P = Data;
for(int i=0;i<4;++i){
(*P)[i].x = TP[i].x;
(*P)[i].y = TP[i].y;
}
}
- Translate
//
// IDL:Polygons/Triangle/Translate:1.0
//
void
Polygons::Triangle_impl::Translate(const Polygons::Position& Offset)
throw(CORBA::SystemException)
{
for(int i=0;i<4;++i){
TP[i].x += Offset.x;
TP[i].y += Offset.y;
}
}
- Rotate
//
// IDL:Polygons/Triangle/Rotate:1.0
//
void
Polygons::Triangle_impl::Rotate(CORBA::Float angle)
throw(CORBA::SystemException)
{
float cosangle, sinangle;
int i;
Polygons::Position V;
Polygons::Position W[4];
cosangle = cos(angle);
sinangle = sin(angle);
/*===========================================
find vector for each side of the triangle
and rotate by angle
===========================================*/
for(i=1;i<3;++i){
V.x = TP[i].x - TP[0].x;
V.y = TP[i].y - TP[0].y;
W[i].x = cosangle*V.x + sinangle*V.y;
W[i].y = -sinangle*V.x + cosangle*V.y;
}
/*===========================================
now translate side vectors back to original
===========================================*/
for(i=1;i<3;++i){
W[i].x += TP[0].x;
W[i].y += TP[0].y;
}
W[0].x = TP[0].x;
W[0].y = TP[0].y;
W[3].x = W[0].x;
W[3].y = W[0].y;
/*=======================================
now store into TP structure
=======================================*/
for(i=0;i<4;++i){
TP[i].x = W[i].x;
TP[i].y = W[i].y;
}
}
5.2.4 The New Implementation Files:
The full implementation files are thus:
Polygons_impl.cpp
1 #include <OB/CORBA.h>
2 #include <Polygons_impl.h>
3
4 //
5 // IDL:Polygons:1.0
6 //
7
8 //
9 // IDL:Polygons/MyTime:1.0
10 //
11 Polygons::MyTime_impl::MyTime_impl(PortableServer::POA_ptr poa)
12 : poa_(PortableServer::POA::_duplicate(poa))
13 {
14 }
15
16 Polygons::MyTime_impl::~MyTime_impl()
17 {
18 }
19
20 PortableServer::POA_ptr
21 Polygons::MyTime_impl::_default_POA()
22 {
23 return PortableServer::POA::_duplicate(poa_);
24 }
25
26 //
27 // IDL:Polygons/MyTime/getgmt:1.0
28 //
29 Polygons::TimeOfDay
30 Polygons::MyTime_impl::getgmt()
31 throw(CORBA::SystemException)
32 {
33 Polygons::TimeOfDay tod;
34
35 time_t time_now = time(0);
36 struct tm *time_p = gmtime(&time_now);
37
38 tod.hour = time_p->tm_hour;
39 tod.minute = time_p->tm_min;
40 tod.second = time_p->tm_sec;
41
42 return tod;
43
44 }
45
46 //
47 // IDL:Polygons/Circle:1.0
48 //
49 Polygons::Circle_impl::Circle_impl(PortableServer::POA_ptr poa)
50 : poa_(PortableServer::POA::_duplicate(poa))
51 {
52 center.x = 0.0;
53 center.y = 0.0;
54 }
55
56 Polygons::Circle_impl::~Circle_impl()
57 {
58 }
59
60 PortableServer::POA_ptr
61 Polygons::Circle_impl::_default_POA()
62 {
63 return PortableServer::POA::_duplicate(poa_);
64 }
65
66 //
67 // IDL:Polygons/Circle/SetPosition:1.0
68 //
69 void
70 Polygons::Circle_impl::SetPosition(Polygons::MyTime_ptr t)
71 throw(CORBA::SystemException)
72 {
73 Polygons::TimeOfDay tod;
74 tod = t->getgmt();
75 cout << "tod = [" << tod.hour << ","
76 << tod.minute << ","
77 << tod.second << "]" << endl;
78 if(tod.hour<12){
79 center.x = tod.minute;
80 center.y = tod.second;
81 }
82 else{
83 center.x = tod.minute;
84 center.y = tod.hour;
85 }
86 cout << "Circle Radius = " << radius << endl;
87 cout << "Circle Center = (" << center.x
88 << "," << center.y << ")" << endl;
89 }
90
91 //
92 // IDL:Polygons/Circle/FindPosition:1.0
93 //
94 void
95 Polygons::Circle_impl::FindPosition(Polygons::Position_out P)
96 throw(CORBA::SystemException)
97 {
98 P.x = center.x;
99 P.y = center.y;
100 }
101
102 //
103 // IDL:Polygons/Circle/SetRadius:1.0
104 //
105 void
106 Polygons::Circle_impl::SetRadius(Polygons::MyTime_ptr t)
107 throw(CORBA::SystemException)
108 {
109 Polygons::TimeOfDay tod;
110 tod = t->getgmt();
111 cout << "tod = [" << tod.hour << ","
112 << tod.minute << ","
113 << tod.second << "]" << endl;
114 if(tod.hour<12){
115 radius = tod.hour;
116 }
117 else{
118 radius = tod.second;
119 }
120
121 cout << "Circle radius = " << radius << endl;
122 cout << "Circle center = (" << center.x << ","
123 << center.y << ")" << endl;
124 }
125
126 //
127 // IDL:Polygons/Circle/FindRadius:1.0
128 //
129 void
130 Polygons::Circle_impl::FindRadius(CORBA::Float_out r)
131 throw(CORBA::SystemException)
132 {
133 r = radius;
134 }
135
136 //
137 // IDL:Polygons/Circle/Translate:1.0
138 //
139 void
140 Polygons::Circle_impl::Translate(const Polygons::Position& Offset)
141 throw(CORBA::SystemException)
142 {
143 center.x += Offset.x;
144 center.y += Offset.y;
145 cout << "Circle radius = " << radius << endl;
146 cout << "Circle center = (" << center.x << "," << center.y << ")" << endl;
147 }
148
149 //
150 // IDL:Polygons/Circle/Rotate:1.0
151 //
152 void
153 Polygons::Circle_impl::Rotate(CORBA::Float angle)
154 throw(CORBA::SystemException)
155 {
156 cout << "Rotating a circle by angle " << angle << " is silly" << endl;
157 }
158
159 //
160 // IDL:Polygons/Triangle:1.0
161 //
162 Polygons::Triangle_impl::Triangle_impl(PortableServer::POA_ptr poa)
163 : poa_(PortableServer::POA::_duplicate(poa))
164 {
165 Polygons::Position *buf = Polygons::TrianglePosition::allocbuf(4);
166 Polygons::TrianglePosition data(4L,buf,1);
167 TP = data;
168 }
169
170 Polygons::Triangle_impl::~Triangle_impl()
171 {
172 }
173
174 PortableServer::POA_ptr
175 Polygons::Triangle_impl::_default_POA()
176 {
177 return PortableServer::POA::_duplicate(poa_);
178 }
179
180 //
181 // IDL:Polygons/Triangle/SetPosition:1.0
182 //
183 void
184 Polygons::Triangle_impl::SetPosition(Polygons::MyTime_ptr t)
185 throw(CORBA::SystemException)
186 {
187 Polygons::TimeOfDay tod;
188
189 tod = t->getgmt();
190 cout << "Inside Triangle Set Position:" << endl;
191 cout << "tod = [" << tod.hour << ","
192 << tod.minute << ","
193 << tod.second << "]" << endl;
194 if(tod.hour<12){
195 TP[0].x = tod.minute;
196 TP[0].y = tod.second;
197
198 TP[1].x = TP[0].x+20.0;
199 TP[1].y = TP[0].y;
200
201 TP[2].x = TP[1].x;
202 TP[2].y =TP[0].y + 20.0;
203
204 TP[3].x = TP[0].x;
205 TP[3].y = TP[0].y;
206 }
207 else{
208 TP[0].x = tod.minute;
209 TP[0].y = tod.hour;
210
211 TP[1].x = TP[0].x+20.0;
212 TP[1].y = TP[0].y;
213
214 TP[2].x = TP[1].x;
215 TP[2].y = TP[0].y + 20.0;
216
217 TP[3].x = TP[0].x;
218 TP[3].y = TP[0].y;
219 }
220 for(int count = 0; count < 4; ++count){
221 cout << "TP[" << count << "] = ("
222 << TP[count].x << ","
223 << TP[count].y << ")";
224 }
225 cout << "Leaving triangle set position " << endl;
226 }
227
228 //
229 // IDL:Polygons/Triangle/FindPosition:1.0
230 //
231 void
232 Polygons::Triangle_impl::FindPosition(Polygons::TrianglePosition_out P)
233 throw(CORBA::SystemException)
234 {
235 P = new Polygons::TrianglePosition;
236 Polygons::Position *buf = Polygons::TrianglePosition::allocbuf(4);
237 Polygons::TrianglePosition Data(4L,buf,1);
238 *P = Data;
239 cout << "Inside triangle find position" << endl;
240 for(int i=0;i<4;++i){
241 (*P)[i].x = TP[i].x;
242 (*P)[i].y = TP[i].y;
243 cout << "Triangle Vertex " << i << " is "
244 << "(" << (*P)[i].x << "," << (*P)[i].y << ")" << endl;
245 }
246 cout << "Leaving triangle find position" << endl;
247 }
248
249 //
250 // IDL:Polygons/Triangle/Translate:1.0
251 //
252 void
253 Polygons::Triangle_impl::Translate(const Polygons::Position& Offset)
254 throw(CORBA::SystemException)
255 {
256 cout << "Inside triangle translate position" << endl;
257 for(int i=0;i<4;++i){
258 TP[i].x += Offset.x;
259 TP[i].y += Offset.y;
260 cout << "Triangle Vertex " << i << " is ("
261 << TP[i].x << "," << TP[i].y << ")" << endl;
262 }
263 cout << "Leaving triangle translate position " << endl;
264 }
265
266 //
267 // IDL:Polygons/Triangle/Rotate:1.0
268 //
269 void
270 Polygons::Triangle_impl::Rotate(CORBA::Float angle)
271 throw(CORBA::SystemException)
272 {
273 float cosangle, sinangle;
274 int i;
275 Polygons::Position V;
276 Polygons::Position W[4];
277
278 cosangle = cos(angle);
279 sinangle = sin(angle);
280
281 cout << "Inside triangle rotate position" << endl;
282 /*===========================================
283 find vector for each side of the triangle
284 and rotate by angle
285 ===========================================*/
286 for(i=1;i<3;++i){
287 V.x = TP[i].x - TP[0].x;
288 V.y = TP[i].y - TP[0].y;
289 W[i].x = cosangle*V.x + sinangle*V.y;
290 W[i].y = -sinangle*V.x + cosangle*V.y;
291 }
292 /*===========================================
293 now translate side vectors back to original
294 ===========================================*/
295 for(i=1;i<3;++i){
296 W[i].x += TP[0].x;
297 W[i].y += TP[0].y;
298 }
299 W[0].x = TP[0].x;
300 W[0].y = TP[0].y;
301 W[3].x = W[0].x;
302 W[3].y = W[0].y;
303 /*=======================================
304 now store into TP structure
305 =======================================*/
306 for(i=0;i<4;++i){
307 TP[i].x = W[i].x;
308 TP[i].y = W[i].y;
309 }
310 for(i=0; i<4; ++i){
311 cout << "TP[" << i << "] = ("
312 << TP[i].x << ","
313 << TP[i].y << ")";
314 }
315 cout << "Leaving triangle rotate position" << endl;
316 }
317
318 //
319 // IDL:Polygons/Rectangle:1.0
320 //
321 Polygons::Rectangle_impl::Rectangle_impl(PortableServer::POA_ptr poa)
322 : poa_(PortableServer::POA::_duplicate(poa))
323 {
324 }
325
326 Polygons::Rectangle_impl::~Rectangle_impl()
327 {
328 }
329
330 PortableServer::POA_ptr
331 Polygons::Rectangle_impl::_default_POA()
332 {
333 return PortableServer::POA::_duplicate(poa_);
334 }
335
336 //
337 // IDL:Polygons/Rectangle/SetPosition:1.0
338 //
339 void
340 Polygons::Rectangle_impl::SetPosition(Polygons::MyTime_ptr t)
341 throw(CORBA::SystemException)
342 {
343 // TODO: Implementation
344 }
345
346 //
347 // IDL:Polygons/Rectangle/FindPosition:1.0
348 //
349 void
350 Polygons::Rectangle_impl::FindPosition(Polygons::RectanglePosition_out P)
351 throw(CORBA::SystemException)
352 {
353 // TODO: Implementation
354 P = new Polygons::RectanglePosition;
355 }
356
357 //
358 // IDL:Polygons/Rectangle/Translate:1.0
359 //
360 void
361 Polygons::Rectangle_impl::Translate(const Polygons::Position& Offset)
362 throw(CORBA::SystemException)
363 {
364 // TODO: Implementation
365 }
366
367 //
368 // IDL:Polygons/Rectangle/Rotate:1.0
369 //
370 void
371 Polygons::Rectangle_impl::Rotate(CORBA::Float angle)
372 throw(CORBA::SystemException)
373 {
374 // TODO: Implementation
375 }
376
377 //
378 // IDL:Polygons/PolygonFactory:1.0
379 //
380 Polygons::PolygonFactory_impl::PolygonFactory_impl(PortableServer::POA_ptr poa)
381 : poa_(PortableServer::POA::_duplicate(poa))
382 {
383 }
384
385 Polygons::PolygonFactory_impl::~PolygonFactory_impl()
386 {
387 }
388
389 PortableServer::POA_ptr
390 Polygons::PolygonFactory_impl::_default_POA()
391 {
392 return PortableServer::POA::_duplicate(poa_);
393 }
394
395 //
396 // IDL:Polygons/PolygonFactory/CreateCircle:1.0
397 //
398 Polygons::Circle_ptr
399 Polygons::PolygonFactory_impl::CreateCircle()
400 throw(CORBA::SystemException)
401 {
402 // Create a Circle object
403 cout << "PolygonFactory:: create a Circle Object" << endl;
404
405 cout << "create Polygons::Circle_impl *Circleimpl" << endl;
406 cout << " = new Polygons::Circle_impl(poa_)" << endl;
407 Polygons::Circle_impl *Circleimpl = new Polygons::Circle_impl(poa_);
408
409 cout << "set PortableServer::ServantBase_var result to " << endl;
410 cout << " Circleimpl;" << endl;
411 PortableServer::ServantBase_var result = Circleimpl;
412
413 cout << "get servant poa" << endl;
414 cout << "call PortableServer::POA_var poa = Circleimpl->_default_POA();"
415 << endl;
416 PortableServer::POA_var poa = Circleimpl->_default_POA();
417
418 cout << "return Circle object" << endl;
419 cout << " call return Circleimpl->_this();" << endl;
420 return Circleimpl->_this();
421 }
422
423 //
424 // IDL:Polygons/PolygonFactory/CreateRectangle:1.0
425 //
426 Polygons::Rectangle_ptr
427 Polygons::PolygonFactory_impl::CreateRectangle()
428 throw(CORBA::SystemException)
429 {
430 // Create a Rectangle object
431 cout << "PolygonFactory:: create a Rectangle Object" << endl;
432
433 cout << "create Polygons::Rectangle_impl *Rectangleimpl" << endl;
434 cout << " = new Polygons::Rectangle_impl(poa_)" << endl;
435 Polygons::Rectangle_impl *Rectangleimpl = new Polygons::Rectangle_impl(poa_);
436
437 cout << "set PortableServer::ServantBase_var result to " << endl;
438 cout << " Rectangleimpl;" << endl;
439 PortableServer::ServantBase_var result = Rectangleimpl;
440
441 cout << "get servant poa" << endl;
442 cout << "call PortableServer::POA_var poa = Rectangleimpl->_default_POA();"
443 << endl;
444 PortableServer::POA_var poa = Rectangleimpl->_default_POA();
445
446 cout << "return Rectangle object" << endl;
447 cout << " call return Rectangleimpl->_this();" << endl;
448 return Rectangleimpl->_this();
449
450 }
451
452 //
453 // IDL:Polygons/PolygonFactory/CreateTriangle:1.0
454 //
455 Polygons::Triangle_ptr
456 Polygons::PolygonFactory_impl::CreateTriangle()
457 throw(CORBA::SystemException)
458 {
459 // Create a Triangle object
460 cout << "PolygonFactory:: create a Triangle Object" << endl;
461
462 cout << "create Polygons::Triangle_impl *Triangleimpl" << endl;
463 cout << " = new Polygons::Triangle_impl(poa_)" << endl;
464 Polygons::Triangle_impl *Triangleimpl = new Polygons::Triangle_impl(poa_);
465
466 cout << "set PortableServer::ServantBase_var result to " << endl;
467 cout << " Triangleimpl;" << endl;
468 PortableServer::ServantBase_var result = Triangleimpl;
469
470 cout << "get servant poa" << endl;
471 cout << "call PortableServer::POA_var poa = Triangleimpl->_default_POA();"
472 << endl;
473 PortableServer::POA_var poa = Triangleimpl->_default_POA();
474
475 cout << "return Triangle object" << endl;
476 cout << " call return Triangleimpl->_this();" << endl;
477 return Triangleimpl->_this();
478 }
479
480 //
481 // IDL:Polygons/PolygonFactory/CreateMyTime:1.0
482 //
483 Polygons::MyTime_ptr
484 Polygons::PolygonFactory_impl::CreateMyTime()
485 throw(CORBA::SystemException)
486 {
487 // Create a MyTime object
488 cout << "PolygonFactory:: create a MyTime Object" << endl;
489
490 cout << "create Polygons::MyTime_impl *MyTimeimpl" << endl;
491 cout << " = new Polygons::MyTime_impl(poa_)" << endl;
492 Polygons::MyTime_impl *MyTimeimpl = new Polygons::MyTime_impl(poa_);
493
494 cout << "set PortableServer::ServantBase_var result to " << endl;
495 cout << " MyTimeimpl;" << endl;
496 PortableServer::ServantBase_var result = MyTimeimpl;
497
498 cout << "get servant poa" << endl;
499 cout << "call PortableServer::POA_var poa = MyTimeimpl->_default_POA();" << endl;
500 PortableServer::POA_var poa = MyTimeimpl->_default_POA();
501
502 cout << "return mytime object" << endl;
503 cout << " call return MyTimeimpl->_this();" << endl;
504 return MyTimeimpl->_this();
505 }
syntax highlighted by Code2HTML, v. 0.8.8b
5.2.5 The New Server:
server2.cpp
1 #include <stdio.h>
2 #include <time.h>
3 #include <iostream.h>
4 #include <fstream.h>
5 #include "mystring.h"
6 #include "charvec1.h"
7 #include <OB/CORBA.h>
8 #include <OB/CosNaming.h>
9 #include "Polygons_skel.h"
10 #include "Polygons_impl.h"
11 #include "utility.h"
12
13 #ifdef HAVE_FSTREAM
14 # include <fstream>
15 #else
16 # include <fstream.h>
17 #endif
18
19 #ifdef HAVE_STD_IOSTREAM
20 using namespace std;
21 #endif
22
23 int
24 run(CORBA::ORB_ptr orb,int argc, char *argv[])
25 {
26 CORBA::Object_var Temp;
27
28 // Get reference to Root POA.
29 cout << "In run" << endl;
30 cout << "resolve initial refs " << endl;
31 CORBA::Object_var poaObj = orb->resolve_initial_references("RootPOA");
32
33 cout << " set rootPoa" << endl;
34 PortableServer::POA_var rootPoa
35 = PortableServer::POA::_narrow(poaObj);
36
37 // Get Reference to POA manager
38 cout << "get reference to poa manager" << endl;
39 PortableServer::POAManager_var manager = rootPoa->the_POAManager();
40
41 cout << "activate poa manager " << endl;
42 manager->activate();
43
44 cout << "get reference to initial naming context" << endl;
45 CORBA::Object_var nsobj;
46 nsobj = orb->resolve_initial_references("NameService");
47
48 cout << "narrow name context" << endl;
49 CosNaming::NamingContext_var inc;
50 inc = CosNaming::NamingContext::_narrow(nsobj);
51
52 // Create an object
53 cout << "create a PolygonFactory MyTime Object" << endl;
54 Polygons::PolygonFactory_impl *PolygonFactoryimpl
55 = new Polygons::PolygonFactory_impl(rootPoa);
56 PortableServer::ServantBase_var servant = PolygonFactoryimpl;
57 Polygons::PolygonFactory_var Polygonfactory
58 = PolygonFactoryimpl->_this();
59
60 cout << "initialize the name of our object to "
61 << "app2.devices" << argv[1] << endl;
62
63 cout << "create app2 context " << endl;
64 CosNaming::NamingContext_var app2;
65 CosNaming::Name name;
66 name.length(1);
67 name[0].id = CORBA::string_dup("app2");
68 name[0].kind = CORBA::string_dup("");
69 cout << "bind context for app2" << endl;
70 app2 = inc->bind_new_context(name);
71
72 CosNaming::NamingContext_var devices;
73 name[0].id = CORBA::string_dup("devices");
74 name[0].kind = CORBA::string_dup("");
75 cout << "bind context for devices" << endl;
76 devices = app2->bind_new_context(name);
77
78 cout << "bind object" << endl;
79 name[0].id = CORBA::string_dup(argv[1]);
80 name[0].kind = CORBA::string_dup("");
81 cout << "bind mytimefactory object" << endl;
82 devices->bind(name,Polygonfactory);
83
84 // Accept requests
85 cout << "run orb" << endl;
86 orb->run();
87
88 return EXIT_SUCCESS;
89 }
90
91 int main(int argc, char* argv[])
92 {
93 int status = 0;
94 CORBA::ORB_var orb;
95
96 int check_ior = 1;
97 int dummy_argc;
98 char *dummy_argv[10];
99
100 //======================================================//
101 // For our Orbacus server we start up with
102 // ./server2: this is argv[0]
103 // option 1 <name of our server object>: this is argv[1]
104 // option 2 -OAbind 127.0.0.1: this is argv[2]
105 // and argv[3]
106 // option 2 -OAhost shortstuff: this is argv[4]
107 // and argv[5]
108 // option 3 -ORBtrace_connections 1 this is argv[6]
109 // and argv[7]
110 //======================================================//
111 if(argc!=8){
112 cout << "start server as ./server2 opt1 opt2 opt3 opt4" << endl;
113 cout << " where opt1 = <name of our served object>" << endl;
114 cout << " where opt2 = -OAbind <ip address of host> " << endl;
115 cout << " where opt3 = -OAhost <host name> " << endl;
116 cout << " where opt4 = -ORBtrace_connections 1 " << endl;
117 exit(-1);
118 }
119 else{
120 for(int p=0;p<argc;++p)
121 cout << "argv[" << p << "] = " << argv[p] << endl;
122 }
123
124 cout << " get name server IOR from file" << endl;
125 cout << " form opt 4 = -ORBnaming <IOR string from file>" << endl;
126 cout << " and form as argument to pass to ORB_init" << endl;
127
128 dummy_argc = argc+2;
129
130 STRING s0(argv[0]);
131 s0.getLabel(&(dummy_argv[0])); //this is ./server2
132
133 STRING s1(argv[1]);
134 s1.getLabel(&(dummy_argv[1])); //this is <name of our served object>
135
136 STRING s2(argv[2]);
137 s2.getLabel(&(dummy_argv[2])); //this is opt 1 -OAbind
138 STRING s3(argv[3]);
139 s3.getLabel(&(dummy_argv[3])); //this is opt 1 address
140
141 STRING s4(argv[4]);
142 s4.getLabel(&(dummy_argv[4])); //this is opt 2 -OAhost
143 STRING s5(argv[5]);
144 s5.getLabel(&(dummy_argv[5])); //this is opt 2 host name
145
146 STRING s6(argv[6]);
147 s6.getLabel(&(dummy_argv[6])); //this is opt 3 -ORBtrace_connections
148 STRING s7(argv[7]);
149 s7.getLabel(&(dummy_argv[7])); //this is opt 3 level <n=1,2,...>
150
151 STRING s8("-ORBnaming");
152 s8.getLabel(&(dummy_argv[8])); //this is -ORBnaming
153
154 STRING NameServerIOR = getIOR();
155 NameServerIOR.getLabel(&(dummy_argv[9]));
156
157 if(check_ior==1){
158 for(int p=0;p<dummy_argc;++p)
159 cout << "dummy_argv[" << p << "] = " << dummy_argv[p] << endl;
160 }
161
162 try{
163 //initialize orb
164 cout << "Initialize orb" << endl;
165 orb = CORBA::ORB_init(dummy_argc,dummy_argv);
166
167 cout << "Call run" << endl;
168 status = run(orb,argc,argv);
169 }
170 catch(const CORBA::Exception& ex){
171 cerr << ex << endl;
172 status = EXIT_FAILURE;
173 }
174 if(!CORBA::is_nil(orb)){
175 try{
176 orb -> destroy();
177 }
178 catch(const CORBA::Exception& ex){
179 cerr << ex << endl;
180 status = EXIT_FAILURE;
181 }
182 }
183 return status;
184 }
syntax highlighted by Code2HTML, v. 0.8.8b
5.2.6 The New Client:
client2.cpp
1 #include <stdio.h>
2 #include <time.h>
3 #include <iostream.h>
4 #include <fstream.h>
5 #include "mystring.h"
6 #include "charvec1.h"
7 #include <OB/CORBA.h>
8 #include <OB/CosNaming.h>
9 #include "Polygons.h"
10 #include "Polygons_impl.h"
11 #include "utility.h"
12
13 int run(CORBA::ORB_ptr orb, int argc, char* argv[])
14 {
15
16 CORBA::Object_var Temp;
17
18 cout << "get reference to initial naming context" << endl;
19 CORBA::Object_var nsobj;
20 nsobj = orb->resolve_initial_references("NameService");
21
22 cout << "narrow name context" << endl;
23 CosNaming::NamingContext_var inc;
24 inc = CosNaming::NamingContext::_narrow(nsobj);
25
26 cout << "initialize the name of our object to look for to "
27 << argv[1] << endl;
28 CosNaming::Name name;
29 name.length(3);
30 name[0].id = CORBA::string_dup("app2");
31 name[0].kind = CORBA::string_dup("");
32 name[1].id = CORBA::string_dup("devices");
33 name[1].kind = CORBA::string_dup("");
34 name[2].id = CORBA::string_dup(argv[1]);
35 name[2].kind = CORBA::string_dup("");
36
37 cout << "resolve name" << endl;
38 try{
39 cout << "resolve new context" << endl;
40 Temp = inc->resolve(name);
41 }
42 catch(const CosNaming::NamingContext::NotFound&){
43 cerr << "No name for object" << endl;
44 throw 0;
45 }
46 catch(const CORBA::Exception& e){
47 cerr << "resolve failed" << e << endl;
48 throw 0;
49 }
50
51 if(CORBA::is_nil(Temp)){
52 cerr << "Nil reference for server object" << endl;
53 throw 0;
54 }
55
56 cout << "narrow to PolygonFactory" << endl;
57 Polygons::PolygonFactory_var Polygonfactory;
58 try{
59 Polygonfactory = Polygons::PolygonFactory::_narrow(Temp);
60 }
61 catch(const CORBA::Exception& e){
62 cerr << "cannot narrow Polygonfactory reference" << e << endl;
63 throw 0;
64 }
65 if(CORBA::is_nil(Polygonfactory)){
66 cerr << "mytime reference is of wrong type" << endl;
67 throw 0;
68 }
69
70 cout << "******************************************" << endl;
71 cout << "use Polygonfactory reference to " << endl;
72 cout << "create a MyTime Object:" << endl;
73 Polygons::MyTime_ptr mytime = Polygonfactory->CreateMyTime();
74 Polygons::TimeOfDay tod = mytime->getgmt();
75
76 cout << "Time of Day is ("
77 << tod.hour << ","
78 << tod.minute << ","
79 << tod.second << "]" << endl;
80
81 cout << "use Polygonfactory reference to " << endl;
82 cout << "create a Circle Object:" << endl;
83 Polygons::Circle_ptr mycircle = Polygonfactory->CreateCircle();
84
85 cout << "Set radius of circle and position" << endl;
86 mycircle->SetRadius(mytime);
87 mycircle->SetPosition(mytime);
88
89 cout << "Read back radius and position" << endl;
90 float r = 0.0;
91 mycircle->FindRadius(r);
92 cout << "Circle radius is " << r << endl;
93
94 Polygons::Position P;
95 mycircle->FindPosition(P);
96 cout << "Circle Position is (" << P.x << "," << P.y << ")" << endl;
97 cout << "******************************************" << endl;
98
99 cout << "******************************************" << endl;
100 cout << "use Polygonfactory reference to " << endl;
101 cout << "create a Triangle Object:" << endl;
102 Polygons::Triangle_ptr mytriangle = Polygonfactory->CreateTriangle();
103
104 cout << "Set triangle position" << endl;
105 mytriangle->SetPosition(mytime);
106
107 Polygons::Position offset;
108 offset.x = 20.0;
109 offset.y = 30.0;
110 cout << "Translate triangle position by ("
111 << offset.x << "," << offset.y << ")" << endl;
112 mytriangle->Translate(offset);
113
114 //Polygons::TrianglePosition_out is *&
115 //a reference to the pointer
116 Polygons::TrianglePosition* Data;
117 mytriangle->FindPosition(Data);
118 cout << "After translation: In client" << endl;
119 for(int i=0;i<4;++i){
120 cout << "New Triangle Vertex " << i << " is "
121 << "(" << (*Data)[i].x << "," << (*Data)[i].y << ")" << endl;
122 }
123 cout << "Translate triangle position by ("
124 << offset.x << "," << offset.y << ")" << endl;
125 mytriangle->Translate(offset);
126
127 float triangle_angle = 30.0/6.28;
128 cout << "Rotate Triangle Position by " << triangle_angle << endl;
129 mycircle->Rotate(triangle_angle);
130 cout << "After rotation: In client" << endl;
131 for(int i=0;i<4;++i){
132 cout << "New Triangle Vertex " << i << " is "
133 << "(" << (*Data)[i].x << "," << (*Data)[i].y << ")" << endl;
134 }
135 return 0;
136 }
137
138 int main(int argc, char* argv[])
139 {
140 int status = 0;
141 CORBA::ORB_var orb;
142
143 int check_ior = 1;
144 int dummy_argc;
145 char *dummy_argv[10];
146
147 //======================================================//
148 // For our Orbacus client we start up with
149 // ./client2: this is argv[0]
150 // option 1 <name of our served object>: this is argv[1]
151 // option 2 -OAbind 127.0.0.1: this is argv[2]
152 // and argv[3]
153 // option 3 -OAhost shortstuff: this is argv[4]
154 // and argv[5]
155 // option 4 -ORBtrace_connections 1 this is argv[6]
156 // and argv[7]
157 //======================================================//
158 if(argc!=8){
159 cout << "start client as ./client2 opt1 opt2 opt3 opt4" << endl;
160 cout << " where opt1 = <name of our served object>" << endl;
161 cout << " where opt2 = -OAbind <ip address of host> " << endl;
162 cout << " where opt3 = -OAhost <host name> " << endl;
163 cout << " where opt4 = -ORBtrace_connections 1 " << endl;
164 exit(-1);
165 }
166 else{
167 for(int p=0;p<argc;++p)
168 cout << "argv[" << p << "] = " << argv[p] << endl;
169 }
170
171 cout << " get name server IOR from file" << endl;
172 cout << " form opt 4 = -ORBnaming <IOR string from file>" << endl;
173 cout << " and form as argument to pass to ORB_init" << endl;
174
175 dummy_argc = argc+2;
176
177 STRING s0(argv[0]);
178 s0.getLabel(&(dummy_argv[0])); //this is ./server2
179
180 STRING s1(argv[1]);
181 s1.getLabel(&(dummy_argv[1])); //this is <name of our served object>
182
183 STRING s2(argv[2]);
184 s2.getLabel(&(dummy_argv[2])); //this is opt 1 -OAbind
185 STRING s3(argv[3]);
186 s3.getLabel(&(dummy_argv[3])); //this is opt 1 address
187
188 STRING s4(argv[4]);
189 s4.getLabel(&(dummy_argv[4])); //this is opt 2 -OAhost
190 STRING s5(argv[5]);
191 s5.getLabel(&(dummy_argv[5])); //this is opt 2 host name
192
193 STRING s6(argv[6]);
194 s6.getLabel(&(dummy_argv[6])); //this is opt 3 -ORBtrace_connections
195 STRING s7(argv[7]);
196 s7.getLabel(&(dummy_argv[7])); //this is opt 3 level <n=1,2,...>
197
198 STRING s8("-ORBnaming");
199 s8.getLabel(&(dummy_argv[8])); //this is -ORBnaming
200
201 STRING NameServerIOR = getIOR();
202 NameServerIOR.getLabel(&(dummy_argv[9]));
203
204 if(check_ior==1){
205 for(int p=0;p<dummy_argc;++p)
206 cout << "dummy_argv[" << p << "] = " << dummy_argv[p] << endl;
207 }
208
209
210 try{
211 //initialize orb
212 cout << "Initialize orb" << endl;
213 orb = CORBA::ORB_init(dummy_argc,dummy_argv);
214
215 cout << "Call run" << endl;
216 status = run(orb,argc,argv);
217 }
218 catch(const CORBA::Exception& ex){
219 cerr << ex << endl;
220 status = EXIT_FAILURE;
221 }
222 if(!CORBA::is_nil(orb)){
223 try{
224 orb -> destroy();
225 }
226 catch(const CORBA::Exception& ex){
227 cerr << ex << endl;
228 status = EXIT_FAILURE;
229 }
230 }
231 return status;
232 }
syntax highlighted by Code2HTML, v. 0.8.8b
5.2.7 The RunTime Results:
Start the name server:
[petersj@shortstuff App]$ rm name-service-ior
rm: remove `name-service-ior'? y
[petersj@shortstuff App]$
/home/petersj/orbacus/bin/nameserv -i > name-service-ior&
[3] 647
next start the server:
[petersj@shortstuff App]$
./server2 Dragon -OAbind 192.168.0.1
-OAhost shortstuff -ORBtrace_connections 1
argv[0] = ./server2
argv[1] = Dragon
argv[2] = -OAbind
argv[3] = 192.168.0.1
argv[4] = -OAhost
argv[5] = shortstuff
argv[6] = -ORBtrace_connections
argv[7] = 1
get name server IOR from file
form opt 4 = -ORBnaming <IOR string from file>
and form as argument to pass to ORB_init
Get the Naming Service IOR from the file
File is available: Get the IOR string
reading IOR from file
IOR:011706082a00000049444c3a6f6f632e636f6d2f436f734e61
6d696e672f4f424e616d696e67436f6e746578743a312e30000608
01000000000000007c000000010102400c0000003139322e313638
2e302e31000e04894028000000abacab305f526f6f74504f410052
6f6f74436f6e74657874504f4100004e616d655365727669636501
000000010000002c000000014e8940010001000200000001000105
200001000901010004000000000101000100010001000105200001
00
strip off ending carriage return
finished reading IOR from file
dummy_argv[0] = ./server2
dummy_argv[1] = Dragon
dummy_argv[2] = -OAbind
dummy_argv[3] = 192.168.0.1
dummy_argv[4] = -OAhost
dummy_argv[5] = shortstuff
dummy_argv[6] = -ORBtrace_connections
dummy_argv[7] = 1
dummy_argv[8] = -ORBnaming
dummy_argv[9] = IOR:011706082a00000049444c3a6f6f632e636
f6d2f436f734e616d696e672f4f424e616d696e67436f6e74657874
3a312e3000060801000000000000007c000000010102400c0000003
139322e3136382e302e31000e04894028000000abacab305f526f6f
74504f4100526f6f74436f6e74657874504f4100004e616d6553657
27669636501000000010000002c000000014e894001000100020000
0001000105200001000901010004000000000101000100010001000
10520000100
Initialize orb
Call run
In run
resolve initial refs
[ incoming: accepting connections
id: TAG_IIOP
local address: 192.168.0.1:1039
hosts: shortstuff ]
set rootPoa
get reference to poa manager
activate poa manager
get reference to initial naming context
narrow name context
[ outgoing: trying to establish connection
timeout: none
id: TAG_IIOP
remote address: 192.168.0.1:1038 ]
[ outgoing: new connection
id: TAG_IIOP
local address: 192.168.0.1:1040
remote address: 192.168.0.1:1038 ]
create a PolygonFactory MyTime Object
initialize the name of our object to app2.devicesDragon
create app2 context
bind context for app2
bind context for devices
bind object
bind mytimefactory object
run orb
finally, start the client:
[petersj@shortstuff App]$
./client2 Dragon -OAbind 192.168.0.1
-OAhost shortstuff -ORBtrace_connections 1
argv[0] = ./client2
argv[1] = Dragon
argv[2] = -OAbind
argv[3] = 192.168.0.1
argv[4] = -OAhost
argv[5] = shortstuff
argv[6] = -ORBtrace_connections
argv[7] = 1
get name server IOR from file
form opt 4 = -ORBnaming <IOR string from file>
and form as argument to pass to ORB_init
Get the Naming Service IOR from the file
File is available: Get the IOR string
reading IOR from file
IOR:011706082a00000049444c3a6f6f632e636f6d2f436f
734e616d696e672f4f424e616d696e67436f6e746578743a
312e3000060801000000000000007c000000010102400c00
00003139322e3136382e302e31000e04894028000000abac
ab305f526f6f74504f4100526f6f74436f6e74657874504f
4100004e616d655365727669636501000000010000002c00
0000014e8940010001000200000001000105200001000901
01000400000000010100010001000100010520000100
strip off ending carriage return
finished reading IOR from file
dummy_argv[0] = ./client2
dummy_argv[1] = Dragon
dummy_argv[2] = -OAbind
dummy_argv[3] = 192.168.0.1
dummy_argv[4] = -OAhost
dummy_argv[5] = shortstuff
dummy_argv[6] = -ORBtrace_connections
dummy_argv[7] = 1
dummy_argv[8] = -ORBnaming
dummy_argv[9] = IOR:011706082a00000049444c3a6f6f6
32e636f6d2f436f734e616d696e672f4f424e616d696e6743
6f6e746578743a312e3000060801000000000000007c00000
0010102400c0000003139322e3136382e302e31000e048940
28000000abacab305f526f6f74504f4100526f6f74436f6e7
4657874504f4100004e616d65536572766963650100000001
0000002c000000014e8940010001000200000001000105200
0010009010100040000000001010001000100010001052000
0100
Initialize orb
Call run
get reference to initial naming context
narrow name context
[ outgoing: trying to establish connection
timeout: none
id: TAG_IIOP
remote address: 192.168.0.1:1038 ]
[ outgoing: new connection
id: TAG_IIOP
local address: 192.168.0.1:1041
remote address: 192.168.0.1:1038 ]
initialize the name of our object to look for to Dragon
resolve name
resolve new context
narrow to PolygonFactory
******************************************
use Polygonfactory reference to
create a MyTime Object:
[ outgoing: trying to establish connection
timeout: none
id: TAG_IIOP
remote address: 192.168.0.1:1039 ]
[ outgoing: new connection
id: TAG_IIOP
local address: 192.168.0.1:1042
remote address: 192.168.0.1:1039 ]
Time of Day is (17,40,3]
use Polygonfactory reference to
create a Circle Object:
Set radius of circle and position
Read back radius and position
Circle radius is 3
Circle Position is (40,17)
******************************************
******************************************
use Polygonfactory reference to
create a Triangle Object:
Set triangle position
Translate triangle position by (20,30)
After translation: In client
New Triangle Vertex 0 is (60,47)
New Triangle Vertex 1 is (80,47)
New Triangle Vertex 2 is (80,67)
New Triangle Vertex 3 is (60,47)
Translate triangle position by (20,30)
Rotate Triangle Position by 4.77707
After rotation: In client
New Triangle Vertex 0 is (60,47)
New Triangle Vertex 1 is (80,47)
New Triangle Vertex 2 is (80,67)
New Triangle Vertex 3 is (60,47)
[ outgoing: closing connection
id: TAG_IIOP
local address: 192.168.0.1:1041
remote address: 192.168.0.1:1038 ]
[ outgoing: closing connection
id: TAG_IIOP
local address: 192.168.0.1:1042
remote address: 192.168.0.1:1039 ]
[petersj@shortstuff App]$