| 1136 | | <para>The following example shows a <function>main()</function> |
|---|
| 1137 | | function for an application that performs all the Tweek |
|---|
| 1138 | | initialization steps. We separate the discussion into two parts: |
|---|
| 1139 | | one part for the CORBA Manager and one part for the Subject |
|---|
| 1140 | | Manager (discussed in the next section).</para> |
|---|
| 1141 | | |
|---|
| 1142 | | <example id="TweekApp.cpp.CORBA-Manager.example"> |
|---|
| 1143 | | <title>TweekApp.cpp</title> |
|---|
| 1144 | | |
|---|
| 1145 | | <programlisting linenumbering="numbered">#include <vpr/vpr.h> |
|---|
| | 1136 | <para>With Tweek 1.3.4 and newer, there are two ways to initialize |
|---|
| | 1137 | the CORBA Manager. The choice of which initialization approach to |
|---|
| | 1138 | use impacts how client-side code makes the connection to the |
|---|
| | 1139 | Subject Manager. The ways to initialize the CORBA Manager are as |
|---|
| | 1140 | follows:</para> |
|---|
| | 1141 | |
|---|
| | 1142 | <orderedlist> |
|---|
| | 1143 | <listitem> |
|---|
| | 1144 | <para>Initialize to use the CORBA Naming Service. This is |
|---|
| | 1145 | the <quote>normal</quote> way that the Tweek CORBA Manager |
|---|
| | 1146 | has been initialized since Tweek was first written. It is a |
|---|
| | 1147 | perfectly valid way to use CORBA, although many people find |
|---|
| | 1148 | the indirection introduced by the CORBA Naming Service (it |
|---|
| | 1149 | runs as a separate process about which both the server side |
|---|
| | 1150 | and the client side must have knowledge) to be a |
|---|
| | 1151 | hassle.</para> |
|---|
| | 1152 | </listitem> |
|---|
| | 1153 | |
|---|
| | 1154 | <listitem> |
|---|
| | 1155 | <para>Initialize to use direct connections to the Subject |
|---|
| | 1156 | Manager. This capability, while not at all new to CORBA, is |
|---|
| | 1157 | new in Tweek 1.3.4. Using this approach, there need not be a |
|---|
| | 1158 | CORBA Naming Service at all. Instead, the client connects |
|---|
| | 1159 | directly to the Subject Manager on the ORB endpoint using a |
|---|
| | 1160 | <literal>corbaloc</literal> URI. The simplicity of this |
|---|
| | 1161 | approach offers a key benefit over the use of the CORBA |
|---|
| | 1162 | Naming Service. However, if there are multiple CORBA Manager |
|---|
| | 1163 | instances running in a single memory space, each must have |
|---|
| | 1164 | its endpoint port number set to a different value. Such a |
|---|
| | 1165 | detail, while still critical in any event, would be hidden |
|---|
| | 1166 | by the use of the CORBA Naming Service.</para> |
|---|
| | 1167 | </listitem> |
|---|
| | 1168 | </orderedlist> |
|---|
| | 1169 | |
|---|
| | 1170 | <para>We next provide code examples of both ways to initialize the |
|---|
| | 1171 | Tweek CORBA Manager.</para> |
|---|
| | 1172 | |
|---|
| | 1173 | <section> |
|---|
| | 1174 | <title>Connections Through the CORBA Naming Service</title> |
|---|
| | 1175 | |
|---|
| | 1176 | <para>The following example shows a <function>main()</function> |
|---|
| | 1177 | function for an application that performs all the Tweek |
|---|
| | 1178 | initialization steps. We separate the discussion into two |
|---|
| | 1179 | parts: one part for the CORBA Manager and one part for the |
|---|
| | 1180 | Subject Manager (discussed in the next section).</para> |
|---|
| | 1181 | |
|---|
| | 1182 | <example id="TweekApp.cpp.CORBA-Manager.naming.example"> |
|---|
| | 1183 | <title><filename>TweekApp.cpp</filename>: CORBA Naming |
|---|
| | 1184 | Service Usage</title> |
|---|
| | 1185 | |
|---|
| | 1186 | <programlisting linenumbering="numbered">#include <vpr/vpr.h> |
|---|
| 1267 | | <calloutlist> |
|---|
| 1268 | | <callout arearefs="TweekApp.cpp.includes.tweek TweekApp.cpp.includes.gen" |
|---|
| 1269 | | id="TweekApp.cpp.includes.co"> |
|---|
| 1270 | | <para>These two headers are typically needed. The first |
|---|
| 1271 | | includes the declaration of the Tweek CORBA Manager, and |
|---|
| 1272 | | the second is the subject implementation declaration, |
|---|
| 1273 | | shown in <xref |
|---|
| 1274 | | linkend="CustomSubjectImpl.h.example" />.</para> |
|---|
| 1275 | | </callout> |
|---|
| 1276 | | |
|---|
| 1277 | | <callout arearefs="TweekApp.cpp.corbamgr.decl" |
|---|
| 1278 | | id="TweekApp.cpp.corbamgr.decl.co"> |
|---|
| 1279 | | <para>In order to use CORBA through Tweek, the CORBA |
|---|
| 1280 | | Manager must be created and initialized. Any number of |
|---|
| 1281 | | these may be created, but in general, only one is needed |
|---|
| 1282 | | per application. Here, we declare an instance of |
|---|
| 1283 | | <classname>tweek::CorbaManager</classname> on the |
|---|
| 1284 | | stack.</para> |
|---|
| 1285 | | </callout> |
|---|
| 1286 | | |
|---|
| 1287 | | <callout arearefs="TweekApp.cpp.corbamgr.init" |
|---|
| 1288 | | id="TweekApp.cpp.corbamgr.init.co"> |
|---|
| 1289 | | <para>Next, we must initialize the CORBA Manager using |
|---|
| 1290 | | the method |
|---|
| 1291 | | <methodname>tweek::CorbaManager::init()</methodname>. The |
|---|
| 1292 | | first argument provides a unique (ideally) identifier for |
|---|
| 1293 | | the local Portable Object Adapter (POA). The second and |
|---|
| 1294 | | third arguments are <varname>argc</varname> and |
|---|
| 1295 | | <varname>argv</varname> respectively. They come in |
|---|
| 1296 | | through the argument list of <function>main()</function> |
|---|
| 1297 | | and represent the command-line arguments. Any arguments |
|---|
| 1298 | | relevant to ORB initialization are removed from |
|---|
| 1299 | | <varname>argv</varname>, and <varname>argc</varname> is |
|---|
| 1300 | | decremented accordingly (it is passed by |
|---|
| 1301 | | reference).</para> |
|---|
| 1302 | | </callout> |
|---|
| 1303 | | |
|---|
| 1304 | | <callout arearefs="TweekApp.cpp.big-try-catch.try TweekApp.cpp.big-try-catch.catch" |
|---|
| 1305 | | id="TweekApp.cpp.big-try-catch.co"> |
|---|
| 1306 | | <para>To ensure that no exceptions go uncaught, we |
|---|
| 1307 | | enclose the bulk of <function>main()</function> in a |
|---|
| 1308 | | try/catch block that catches any exception. This is |
|---|
| 1309 | | handled by the argument list passed to the catch block, |
|---|
| 1310 | | <literal>(...)</literal>. This is the equivalent of |
|---|
| 1311 | | catching <classname>java.lang.Exception</classname> in |
|---|
| 1312 | | Java.</para> |
|---|
| 1313 | | </callout> |
|---|
| 1314 | | </calloutlist> |
|---|
| 1315 | | </example> |
|---|
| | 1310 | <calloutlist> |
|---|
| | 1311 | <callout arearefs="TweekApp.cpp.includes.tweek TweekApp.cpp.includes.gen" |
|---|
| | 1312 | id="TweekApp.cpp.includes.co"> |
|---|
| | 1313 | <para>These two headers are typically needed. The |
|---|
| | 1314 | first includes the declaration of the Tweek CORBA |
|---|
| | 1315 | Manager, and the second is the subject implementation |
|---|
| | 1316 | declaration, shown in <xref |
|---|
| | 1317 | linkend="CustomSubjectImpl.h.example" />.</para> |
|---|
| | 1318 | </callout> |
|---|
| | 1319 | |
|---|
| | 1320 | <callout arearefs="TweekApp.cpp.corbamgr.decl" |
|---|
| | 1321 | id="TweekApp.cpp.corbamgr.decl.co"> |
|---|
| | 1322 | <para>In order to use CORBA through Tweek, the CORBA |
|---|
| | 1323 | Manager must be created and initialized. Any number of |
|---|
| | 1324 | these may be created, but in general, only one is |
|---|
| | 1325 | needed per application. Here, we declare an instance |
|---|
| | 1326 | of <classname>tweek::CorbaManager</classname> on the |
|---|
| | 1327 | stack.</para> |
|---|
| | 1328 | </callout> |
|---|
| | 1329 | |
|---|
| | 1330 | <callout arearefs="TweekApp.cpp.corbamgr.init" |
|---|
| | 1331 | id="TweekApp.cpp.corbamgr.init.co"> |
|---|
| | 1332 | <para>Next, we must initialize the CORBA Manager using |
|---|
| | 1333 | the method |
|---|
| | 1334 | <methodname>tweek::CorbaManager::init()</methodname>. |
|---|
| | 1335 | The first argument provides a unique (ideally) |
|---|
| | 1336 | identifier for the local Portable Object Adapter |
|---|
| | 1337 | (POA). The second and third arguments are |
|---|
| | 1338 | <varname>argc</varname> and <varname>argv</varname> |
|---|
| | 1339 | respectively. They come in through the argument list |
|---|
| | 1340 | of <function>main()</function> and represent the |
|---|
| | 1341 | command-line arguments. Any arguments relevant to ORB |
|---|
| | 1342 | initialization are removed from |
|---|
| | 1343 | <varname>argv</varname>, and <varname>argc</varname> |
|---|
| | 1344 | is decremented accordingly (it is passed by |
|---|
| | 1345 | reference).</para> |
|---|
| | 1346 | </callout> |
|---|
| | 1347 | |
|---|
| | 1348 | <callout arearefs="TweekApp.cpp.big-try-catch.try TweekApp.cpp.big-try-catch.catch" |
|---|
| | 1349 | id="TweekApp.cpp.big-try-catch.co"> |
|---|
| | 1350 | <para>To ensure that no exceptions go uncaught, we |
|---|
| | 1351 | enclose the bulk of <function>main()</function> in a |
|---|
| | 1352 | try/catch block that catches any exception. This is |
|---|
| | 1353 | handled by the argument list passed to the catch |
|---|
| | 1354 | block, <literal>(...)</literal>. This is the |
|---|
| | 1355 | equivalent of catching |
|---|
| | 1356 | <classname>java.lang.Exception</classname> in |
|---|
| | 1357 | Java.</para> |
|---|
| | 1358 | </callout> |
|---|
| | 1359 | </calloutlist> |
|---|
| | 1360 | </example> |
|---|
| | 1361 | </section> |
|---|
| | 1362 | |
|---|
| | 1363 | <section> |
|---|
| | 1364 | <title>Direct Subject Manager Connections</title> |
|---|
| | 1365 | |
|---|
| | 1366 | <para>Just as in the previous subsection, the following example |
|---|
| | 1367 | shows a <function>main()</function> function for an application |
|---|
| | 1368 | that performs all the Tweek initialization steps. The code is |
|---|
| | 1369 | nearly identical except for one key difference: we invoke |
|---|
| | 1370 | <methodname>tweek::CorbaManager::initDirect()</methodname> |
|---|
| | 1371 | instead of |
|---|
| | 1372 | <methodname>tweek::CorbaManager::init()</methodname>. See the |
|---|
| | 1373 | call-out after the example code for more details.</para> |
|---|
| | 1374 | |
|---|
| | 1375 | <example id="TweekApp.cpp.CORBA-Manager.direct.example"> |
|---|
| | 1376 | <title><filename>TweekApp.cpp</filename>: Direct Object |
|---|
| | 1377 | Connection</title> |
|---|
| | 1378 | |
|---|
| | 1379 | <programlisting linenumbering="numbered">#include <vpr/vpr.h> |
|---|
| | 1380 | #include <vpr/Thread/Thread.h> |
|---|
| | 1381 | #include <vpr/Util/Debug.h> |
|---|
| | 1382 | #include <tweek/CORBA/CorbaManager.h> |
|---|
| | 1383 | |
|---|
| | 1384 | #include <CustomSubjectImpl.h> |
|---|
| | 1385 | |
|---|
| | 1386 | /** |
|---|
| | 1387 | * This application starts the CORBA server for the C++ side |
|---|
| | 1388 | * of the test. |
|---|
| | 1389 | */ |
|---|
| | 1390 | int main(int argc, char* argv[]) |
|---|
| | 1391 | { |
|---|
| | 1392 | tweek::CorbaManager mgr; |
|---|
| | 1393 | |
|---|
| | 1394 | // The first thing we have to do is initialize the Tweek |
|---|
| | 1395 | // CORBA Manager. If this fails, we're out of luck. |
|---|
| | 1396 | try |
|---|
| | 1397 | { |
|---|
| | 1398 | // Initialize the CORBA Manager to use a direct |
|---|
| | 1399 | // connection to the Subject Manager. The ORB endpoint |
|---|
| | 1400 | // will be bound to port 12345 on the default network |
|---|
| | 1401 | // interface. |
|---|
| | 1402 | if ( mgr.initDirect("example", argc, argv, "", 12345) ) <co |
|---|
| | 1403 | id="TweekApp.cpp.mgr.initDirect.gen" |
|---|
| | 1404 | linkends="TweekApp.cpp.corbamgr.init.co" /> |
|---|
| | 1405 | { |
|---|
| | 1406 | bool status(false); |
|---|
| | 1407 | |
|---|
| | 1408 | // Once the CORBA Manager is initialized, we need |
|---|
| | 1409 | // to create a Subject Manager. This will hold our |
|---|
| | 1410 | // CustomSubject object. |
|---|
| | 1411 | try |
|---|
| | 1412 | { |
|---|
| | 1413 | status = mgr.createSubjectManager(); |
|---|
| | 1414 | |
|---|
| | 1415 | // If we were able to create the Subject Manager, |
|---|
| | 1416 | // now we register our objects with it. |
|---|
| | 1417 | if ( status ) |
|---|
| | 1418 | { |
|---|
| | 1419 | // First, create real instances of the C++ |
|---|
| | 1420 | // object that will be the CORBA servant. This |
|---|
| | 1421 | // must be allocated on the heap. |
|---|
| | 1422 | mymod::CustomubjectImpl* custom_subj = |
|---|
| | 1423 | new mymod::CustomSubjectImpl(); |
|---|
| | 1424 | |
|---|
| | 1425 | // Now we try to register the subject and give |
|---|
| | 1426 | // it a symbolic, easy-to-remember name. |
|---|
| | 1427 | try |
|---|
| | 1428 | { |
|---|
| | 1429 | mgr.getSubjectManager()-> |
|---|
| | 1430 | registerSubject(slider_subj, "CustomSubject"); |
|---|
| | 1431 | } |
|---|
| | 1432 | catch (...) |
|---|
| | 1433 | { |
|---|
| | 1434 | vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) |
|---|
| | 1435 | << "Failed to register subject\n" |
|---|
| | 1436 | << vprDEBUG_FLUSH; |
|---|
| | 1437 | } |
|---|
| | 1438 | |
|---|
| | 1439 | // We are done with our pointer to the servant. |
|---|
| | 1440 | slider_subj->_remove_ref(); |
|---|
| | 1441 | } |
|---|
| | 1442 | } |
|---|
| | 1443 | catch (CORBA::Exception& ex) |
|---|
| | 1444 | { |
|---|
| | 1445 | vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) |
|---|
| | 1446 | << "Caught an unknown CORBA exception when " |
|---|
| | 1447 | << "trying to register!\n" << vprDEBUG_FLUSH; |
|---|
| | 1448 | } |
|---|
| | 1449 | |
|---|
| | 1450 | if ( ! status ) |
|---|
| | 1451 | { |
|---|
| | 1452 | vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) |
|---|
| | 1453 | << "Failed to register Subject Manager instance\n" |
|---|
| | 1454 | << vprDEBUG_FLUSH; |
|---|
| | 1455 | } |
|---|
| | 1456 | |
|---|
| | 1457 | std::cout << "Press 'x' to exit" << std::endl; |
|---|
| | 1458 | char input; |
|---|
| | 1459 | |
|---|
| | 1460 | // Loop forever so that we can act sort of like |
|---|
| | 1461 | // a server. |
|---|
| | 1462 | while ( 1 ) |
|---|
| | 1463 | { |
|---|
| | 1464 | std::cin >> input; |
|---|
| | 1465 | if ( input == 'x' ) |
|---|
| | 1466 | { |
|---|
| | 1467 | break; |
|---|
| | 1468 | } |
|---|
| | 1469 | else |
|---|
| | 1470 | { |
|---|
| | 1471 | vpr::System::msleep(100); |
|---|
| | 1472 | } |
|---|
| | 1473 | } |
|---|
| | 1474 | } |
|---|
| | 1475 | else |
|---|
| | 1476 | { |
|---|
| | 1477 | vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) |
|---|
| | 1478 | << "CORBA failed to initialize\n" |
|---|
| | 1479 | << vprDEBUG_FLUSH; |
|---|
| | 1480 | } |
|---|
| | 1481 | } |
|---|
| | 1482 | catch (...) |
|---|
| | 1483 | { |
|---|
| | 1484 | vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) |
|---|
| | 1485 | << "Caught an unknown exception!\n" |
|---|
| | 1486 | << vprDEBUG_FLUSH; |
|---|
| | 1487 | } |
|---|
| | 1488 | |
|---|
| | 1489 | vprDEBUG(vprDBG_ALL, vprDBG_CRITICAL_LVL) |
|---|
| | 1490 | << "Exiting\n" << vprDEBUG_FLUSH; |
|---|
| | 1491 | |
|---|
| | 1492 | return 0; |
|---|
| | 1493 | }</programlisting> |
|---|
| | 1494 | |
|---|
| | 1495 | <calloutlist> |
|---|
| | 1496 | <callout arearefs="TweekApp.cpp.mgr.initDirect.gen" |
|---|
| | 1497 | id="TweekApp.cpp.initDirect.co"> |
|---|
| | 1498 | <para>This is the only difference in the code with |
|---|
| | 1499 | respect to the example shown in <xref |
|---|
| | 1500 | linkend="TweekApp.cpp.CORBA-Manager.naming.example" />. |
|---|
| | 1501 | Instead of using |
|---|
| | 1502 | <methodname>tweek::CorbaManager::init()</methodname>, |
|---|
| | 1503 | we call |
|---|
| | 1504 | <methodname>tweek::CorbaManager::initDirect()</methodname> |
|---|
| | 1505 | and provide the address and port number for the ORB |
|---|
| | 1506 | endpoint. In this case, we have used an empty string |
|---|
| | 1507 | for the endpoint address to indicate that we want to |
|---|
| | 1508 | bind to the default network interface.</para> |
|---|
| | 1509 | </callout> |
|---|
| | 1510 | </calloutlist> |
|---|
| | 1511 | </example> |
|---|
| | 1512 | </section> |
|---|