Hands-on on VisiBroker5.1 for C++ and Java (1)

40 篇文章 0 订阅
31 篇文章 0 订阅

下面的是几年前刚接触VB时的学习笔记,仅供参考。

 

Chapter 1                   Development Environment

Cautions:

1.       VisiBroker 5.1 can only work with JDK1.3.1or later.

If you already other version of JDK and/or JBuilder installed on your computer, please remove them from the environmental variables if there is any. Such as:

Unistall JBuilder,

Remove the environmental variables such as JAVA_HOME, J2EE_HOME,

Remove related items from CLASSPATH and PATH.

Of course, you should store all the environmental variables to be changed in a file (eg. EnvironmentalVariables.txt) for future restoring the original programming environment.

 

2.       Shipped with VisiBroker 5.1, there is a version of JDK v1.3.1.0.4, we will use this edition of JDK other than any versions else. It locates E:/BES/jdk if you install Borland AppServer VisiBroker Edition under the directory of E:/BES where the VisiBroker is installed.

 

3.       Add E:/BES/BIN and E:/BES/jdk/bin to your path environmental variable, makes it look like:

path=e:/bes/bin;e:/bes/jdk/bin;…

It’s better to put them in the very front of the path variable just after the “=” sign for example, to ensure the compilation will use right JDK version.

 

4.       Create a new environmental variable name VBROKERDIR, and set its value to “E:/BES” where the VisiBroker is installed.

 

5.       If you write C++ applications, you will use the NAMKE tools from Visual C++. Before using this tool, you should run vcvars32.bat first.

 

6.       When using vbmake to re-make the java programs, there is a bug. The solution is to delete all the generated .class files (and the entrie package such Bank in example1), you can do this by vbmake clean. Similarly, delete all the generated files for C++, you can do it by nmake –f Makefile.cpp clean.

 

Now, let’s get down to write the code.


Chapter 2                   Example1

 

2.1             Writing the IDL file

 

module Bank

{

       interface Account

{

               float balance();

       };

 

       interface AccountManager

{

               Account open(in string name);

       };

};

 

save it as Bank.idl.


2.2             Using Java to Write the Application

1. Compile the .idl file as

         prompt>idl2java Bank.idl

   The above command will generate a subdirectory named Bank (see the module Bank in the .idl file) which contains the following 14 files:

         _AccountManagerStub.java:

stub code for AccountManager object on the client side

        

_AccountStub.java:

stub code of Account object on the client side.

 

         Account.java:

The Account interface declaration.

 

         AccountHelper.java:

Declares the AccountHelper class, which defines helpful utility methods.

 

         AccountHolder.java:

Declares the AccountHolder class, which provides a holder for passing Account objects.

 

         AccountManager.java:

The AccountManager interface declaration.

 

         AccountManagerHelper.java:

Declares the AccountManagerHelper class, which defines helpful utility methods.

        

AccountManagerHolder.java:

Declare the AccountManagerHolder class, which provides a holder for passing AccountManager objects.

 

         AccountManagerOperation.java:

         This interface provides declares the method signatures defined in the AccountManager interface in the

Bank.idl

 

         AccountManagerPOA.java:

         POA servant code for the AccountManager object implementation on the server side.

 

         AccountManagerPOATie.java:

         Class used to implement the AccountManager object on the server side using the tie mechanism.

 

         AccountOperations.java:

         This interface provides declares the method signatures defined in the Account interface in the Bank.idl file.

 

         AccountPOA.java:

         POA servant code for the Account object implementation on the server side.

         AccountPOATie.java:

         Class used to implement the Account object on the server side suing the tie mechanism.

 

         Explanation:

         Helper classes: It contains some important static methods such as bind and narrow.

 

         Holder classes:

A Holder class is provided for all basic IDL types in the org.omg.CORBA package. Holder classes are also generated by the idl2java compiler for all user-defined types. The suffix Holder is added to the class name that is generated for user-defined types. Each Holder has a set of constructors and a value member, which is the typed value.

 

         Operations classes:

         It contains the interface defintions of the methods and constants declared for <interface-name> in the idl file.

 

         So, 7 related file will be generated for 1 interface defined in the .idl file.

         _<interface-name>Stub.java

         <interface_name>.java

         <interface_name>Helper.java

         <interface_name>Holder.java

         <interface_name>Operations.java

         <interface_name>POA.java

         <interface_name>POATie.java

 

         when use vbmake.bat the job idl2java did will be done automatically.

 

2. The Client class implements the client application which obtains the current balance of a bank account. The

Bank client program performs these steps:

         Initializes the VisiBroker ORB

         Binds to an AccountManager object

         Obtains an Account object by invoking open on the AccountManager object

         Obtains the balance by invoking balance on the Account object

        

        

         //Client.java

         public class Client

         {

                   public static void main(String[] args)

                   {

                            // Initialize the ORB

                            org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);

                            // Get the manager ID

byte[] managerId = “Bankmanager”.getBytes();

                            // Locate an account manager. Give the full POA name and servant ID.

                            Bank.AccountManager manager =

Bank.AccountManagerHelper.bind(orb, “/bank_agent_poa”, managerId);

                             /* -added by Patrick, the following snippet is OK

                        com.inprise.vbroker.CORBA.BindOptions bindOptions = new com.inprise.vbroker.CORBA.BindOptions(false, true);

                            Bank.AccountManager manager =

                            Bank.AccountManagerHelper.bind(orb, "/bank_agent_poa", managerId, "192.168.0.198", bindOptions);

                            */

// User args[0] as the account name, or a default.

                            String name = args.length > 0 ? args[0] : “Patrick H. Huang”;

                            // Request the account manager to open a named account.

                            Bank.Account account = manager.open(name);

                            // Get the balance of the acocunt.

                            Float balance = account.balance();

                            // Print out the balance.

                            System.out.println(“The balance in “ + name + “’s account is $” + balance);

}

}

 

complementary notes:

byte[] String.getCode(String charsetName)

Encodes this String into a sequence of bytes using the named charset, storing the result into a new byte array.

 

static ORB org.omg.CORBA.ORB.init(String[] args, Properties props)

Creates a new ORB instance for a standalone application.

args - command-line arguments for the application's main method; may be null

props - application-specific properties; may be null, see the following reference program.

 

Reference program:

import HelloApp.*;                                // The package containing our stubs.

import org.omg.CosNaming.*;           // HelloClient will use the naming service.

import org.omg.CORBA.*;                            // All CORBA applications need these classes.

import java.util.Properties;

 

public class HelloClient

{

         public static void main(String args[])

         {

                   try

                   {

                            // The following 4 lines are OK!

                            Properties props = new Properties();

                            props.put("org.omg.CORBA.ORBInitialHost", "127.0.0.1");

                            props.put("org.omg.CORBA.ORBInitialPort", "1050");

                            ORB orb = ORB.init(args, props);

                            // For applet, it should be "ORB orb = ORB.init(this, props);"

 

                            //ORB orb = ORB.init(args, null);

                            org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");

                            NamingContext ncRef = NamingContextHelper.narrow(objRef);

                            NameComponent nc = new NameComponent("Hello1&2", "");

                            NameComponent path[] = {nc};

                            Hello helloRef = HelloHelper.narrow(ncRef.resolve(path));

                            String Hello1 = helloRef.sayHello1();

                            System.out.println(Hello1);       

                           

                            String Hello2 = helloRef.sayHello2();

                            System.out.println(Hello2);       

                   }

                   catch(Exception e)

                   {

                            System.out.println("ERROR: " + e);

                            e.printStackTrace(System.out);

                   }

         }

}

 

because in the init method in above reference program we use the second parameter props, so we can just run the client as:

prompt>java HelloClient

otherwise, you should run the client as:

prompt>java HelloClient -ORBInitialPort 1050

 

 

Different Signatures of Bind method and their parameters (defined in AccountManagerHelper.java):

public static Bank.AccountManager bind (org.omg.CORBA.ORB orb)

{

    return bind(orb, null, null, null);

}

 

public static Bank.AccountManager bind (org.omg.CORBA.ORB orb, java.lang.String name)

{

    return bind(orb, name, null, null);

}

 

public static Bank.AccountManager bind (org.omg.CORBA.ORB orb,

                                     java.lang.String name,

                                     java.lang.String host,

com.inprise.vbroker.CORBA.BindOptions _options)

{

if (!(orb instanceof com.inprise.vbroker.CORBA.ORB))

{

             throw new org.omg.CORBA.BAD_PARAM();

    }

    return narrow(((com.inprise.vbroker.CORBA.ORB)orb).bind(id(), name, host, _options), true);

 }

 

public static Bank.AccountManager bind (org.omg.CORBA.ORB orb, java.lang.String fullPoaName, byte[] oid)

{

    return bind(orb, fullPoaName, oid, null, null);

}

 

public static Bank.AccountManager bind (org.omg.CORBA.ORB orb,

                                     java.lang.String fullPoaName,

byte[] oid,

java.lang.String host,

com.inprise.vbroker.CORBA.BindOptions _options)

{

if (!(orb instanceof com.inprise.vbroker.CORBA.ORB))

{

             throw new org.omg.CORBA.BAD_PARAM();

    }

return narrow(((com.inprise.vbroker.CORBA.ORB)orb).bind(fullPoaName, oid, host, _options), true);

}

 

VisiBroker osagent is a dynamic and distributed directory service, it provides tool for the client side program and object implemenation. osagent must be on at least one host in a LAN. When client invoke certain object’ s bind() method, it will look for osagent automatically. The osagent locates the designated implementation, so that the link can be established between client and the related implementation.To a client, the communication with osagent is transparent, but limited in LAN.

 

The above highlighted lines is just for the purpose of effiency.

 

3. Implementation of AccountManger and Account interface

 

// AccountManagerImpl.java

import org.omg.PortableServer.*;

 

import java.util.*;

 

public class AccountManagerImpl extends Bank.AccountManagerPOA

{

       public synchronized Bank.Account open(String name)

{

               // Lookup the account in the account dictionary.

               Bank.Account account = (Bank.Account) _accounts.get(name);

   

// If there was no account in the dictionary, create one.

               if(account == null)

{

                      // Make up the account's balance, between 0 and 1000 dollars.

                      float balance = Math.abs(_random.nextInt()) % 100000 / 100f;

                      // Create the account implementation, given the balance.

                      AccountImpl accountServant = new AccountImpl(balance);

                      try

{

                             // Activate it on the default POA which is root POA for this servant

                             account = Bank.AccountHelper.narrow(_default_POA().servant_to_reference(accountServant));

                      }

catch (Exception e)

{

                             e.printStackTrace();

                      }

                      // Print out the new account.

                      System.out.println("Created " + name + "'s account: " + account);

                      // Save the account in the account dictionary.

                      _accounts.put(name, account);

               }

               // Return the account.

               return account;

       }

       private Dictionary _accounts = new Hashtable();

       private Random _random = new Random();

}

 

 

 

// AccountImpl.java

 

public class AccountImpl extends Bank.AccountPOA

{

       public AccountImpl(float balance)

{

               _balance = balance;

       }

       public float balance()

{

               return _balance;

       }

       private float _balance;

}

 

4. Server

The following file implments the Server class for the server side of our banking example. The code samples below are example of server side program for Java. The server program does the following:

                   Initializes the Object Request Broker;

                   Creates a Protable Object Adapter with the required policies;

                   Creates the account manager servant object;

                   Activates the servant object;

                   Activates the POA manager and the POA;

                   Waits for incoming requests.

 

// Server.java

import org.omg.PortableServer.*;

 

public class Server

{

public static void main(String[] args)

{

               try

{

                      // Initialize the ORB.

                      org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);

                      // get a reference to the root POA

                      POA rootPOA = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));

 

                      // Create policies for our persistent POA

                      org.omg.CORBA.Policy[] policies =

{

                             rootPOA.create_lifespan_policy(LifespanPolicyValue.PERSISTENT)

                      };

                      // Create myPOA with the right policies

                      POA myPOA = rootPOA.create_POA( "bank_agent_poa", rootPOA.the_POAManager(), policies );

                      // Create the servant

                      AccountManagerImpl managerServant = new AccountManagerImpl();

                      // Decide on the ID for the servant

                      byte[] managerId = "BankManager".getBytes();

                      // Activate the servant with the ID on myPOA

                      myPOA.activate_object_with_id(managerId, managerServant);

 

                      // Activate the POA manager

                      rootPOA.the_POAManager().activate();

 

                      System.out.println(myPOA.servant_to_reference(managerServant) + " is ready.");

                      // Wait for incoming requests

                      orb.run();

               }

               catch (Exception e)

{

                      e.printStackTrace();

               }

       }

}

 

complementary notes:

 

org.omg.PortableServer.POA

A POA object manages the implementation of a collection of objects. The POA supports a name space for the objects, which are identified by Object Ids. A POA also provides a name space for POAs. A POA is created as a child of an existing POA, which forms a hierarchy starting with the root POA. A POA object must not be exported to other processes, or externalized with ORB::object_to_string

 

org.omg.PortableServer.POA. create_POA

public POA create_POA(String adapter_name,
                      POAManager a_POAManager,
                      Policy[] policies)
               throws AdapterAlreadyExists,
                      InvalidPolicy

This operation creates a new POA as a child of the target POA.

Parameters:

adapter_name - identifies the new POA with respect to other POAs with the same parent POA.

a_POAManager - specifies the POA Manager to be associated with the new POA.

policies - specifies policy objects to be associated with the POA to control its behavior.

Throws:

AdapterAlreadyExists - specifies that the target POA already has a child POA with the specified name.

InvalidPolicy - is raised if any of the policy objects are not valid for the ORB, or are in conflict, or require an administrative action that has not been performed.

 

org.omg.PortableServer.POA.activate_object_with_id

public void activate_object_with_id(byte[] id, Servant p_servant)
                             throws ServantAlreadyActive,
                                    ObjectAlreadyActive,
                                    WrongPolicy

This operation enters an association between the specified Object Id and the specified servant in the Active Object Map.

Parameters:

id - object id for the object to be activated.

p_servant - servant to be associated with the object.

Throws:

ServantAlreadyActive - raised if the POA has the UNIQUE_ID policy and the servant is already in the Active Object Map.

ObjectAlreadyActive - raised if the object is already active in the POA.

WrongPolicy - raised if the RETAIN policy is is not specified.

 

org.omg.CORBA.ORB.resolv_initial_references

public abstract Object resolve_initial_references(String object_name) throws InvalidName

Resolves a specific object reference from the set of available initial service names.

Parameters:

object_name - the name of the initial service as a string

Returns:

the object reference associated with the given name

Throws:

InvalidName - if the given name is not associated with a known service

 

org.omg.ProtableServer.POAHelper.narrow

public static POA narrow(Object obj)

 

org.omg.PortableServer.POA.servant_to_reference

public Object servant_to_reference(Servant p_servant) throws ServantNotActive, WrongPolicy

Parameters:

p_servant - servant for which the object reference needs to be obtained.

Returns:

object reference associated with the servant.

Throws:

WrongPolicy - if the operation is not invoked in the context of executing a request on the specified servant and the required policies are not present.

ServantNotActive - if the above specified policies and rules are not met.

 

org.omg.PortableServer.Servant._default_POA

public POA _default_POA()

Returns the root POA from the ORB instance associated with the servant. Subclasses may override this method to return a different POA.

Returns:

default_POA the POA associated with the Servant.

 

 

 

5.  vbmake.bat

 

@echo off

rem Makefile

 

if "%1"=="" goto all

if "%1"=="clean" goto clean

goto usage

 

:all

echo Building the basic/bank_agent example ...

call idl2java Bank.idl

vbjc Client.java

vbjc Server.java

goto end

 

:clean

if "%OS%"=="Windows_NT" goto nt

deltree /y Bank

del *.class

goto end

:nt

rd /s /q Bank

del /q *.class

goto end

 

:usage

echo Usage: vbmake [clean]

 

:end

 

 

6. Make all the files by run

         vbmake

 

7. Start osagent by

         prompt>osagent

         or

         start it from the Start/program file/…

 

8. Start the Server by

         prompt>vbj Server

 

9. Start the Client by

         prompt>vbj Client

 

10. Results

Server side

 

          Fig. 1

         Client Side

        

 

         Fig. 2

 

 

2.3             Using C++ to Write the Application

1.       compile the Bank.idl file as

prompt>idl2cpp Bank.idl

The idl2cpp compiler generates four files from the Bank.idl:

 

Bank_c.hh:

Contains the definitions for the Account and AccountManager

 

Bank_c.cc:

Contians internal stub routines used by the client.

 

Bank_s.hh:

Contians the definitions for the AccountPOA and AccountManagerPOA servant classes.

 

Bank_s.cc:

Contians the internal routines used by the server.

 

We will use the Bank_c.hh and Bank_c.cc files to build the client application.

Bank_s.hh and Bank_s.cc are for building the server object.

 

If you compile the Bank.idl file as:

prompt>idl2cpp –src_suffix cpp Bank.idl

then, Bank_c.cc and Bank_s.cc will be named as Bank_c.cpp and Bank_s.cpp respectively.

 

2.       The Client program implements the client application which obtains the current balance of a bank account. The bank client program performs these steps:

Initializes the VisiBroker ORB

Binds to an AccountManager object.

Obtains the balance of the Account using the object reference returned by bind().

Obtains the balance by invoking balance on the Account object.

 

//Client.c

#include "Bank_c.hh"

#include "corba.h"    //corba.h should be included when using BindOptions structure

#include "time.h"       // OK on Unix and Window, the smallest time unit is SECOND

#include "sys/timeb.h"      // specifically for Windows only, the smallest time unit is MILLISECOND

 

// USE_STD_NS is a define setup by VisiBroker to use the std namespace

USE_STD_NS

 

int main(int argc, char* const* argv)

{

       try

{

               //time_t t1 = time(NULL);            // will be OK on Unix and Windows, to get the time in second

                   struct _timeb timebuffer1;                   // specifically for Windows

                   _ftime(&timebuffer1);                           // specifically for Windows, to get the time in millisecond

 

// Initialize the ORB.

               CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

 

               // Get the manager Id

               PortableServer::ObjectId_var managerId =

                        PortableServer::string_to_ObjectId("BankManager"); //should be identical to the declaration in Server

 

               // Locate an account manager. Give the full POA name and the servant ID.

                   /*

               Bank::AccountManager_var manager =

                  Bank::AccountManager::_bind("/bank_agent_poa", managerId);  //see complementary notes**********

                   */

                  //The above line of code can be replaced by the following one. See compelementary notes************************

                   HelloApp::Hello_var helloServant =

HelloApp::Hello::_bind("/hello", servantID, "127.0.0.1", CORBA_Object::_default_bind_options(), orb);

               // use argv[1] as the account name, or a default.

               const char* name = argc > 1 ? argv[1] : "Jack B. Quick";

 

               // Request the account manager to open a named account.

               Bank::Account_var account = manager->open(name);

 

               // Get the balance of the account.

               CORBA::Float balance;

               balance  = account->balance();

 

               // Print out the balance.

               cout << "The balance in " << name << "'s account is $" << balance << endl;

 

                   //time_t t2 = time(NULL);            // will be OK on Unix and Windows, to get the time in second

                   struct _timeb timebuffer2;                   // specifically for Windows

                   _ftime(&timebuffer2);                           // specifically for Windows, to get the time in millisecond

                  

                   //timebuffer1.time’s unit is second, timebuffer1.millitm’s unit is millisecond.

                   cout << (timebuffer2.time - timebuffer1.time) * 1000 + timebuffer2.millitm - timebuffer1.millitm

 << " milliseconds elapsed." << endl;

       }

       catch(const CORBA::Exception& e)

{

               cerr << e << endl;

               return 1;

       }

       return 0;

}

 

complementary notes:

 

in Hello_c.hh, the _bind function are defined as:

    static Hello_ptr _bind(const char *_object_name = (const char*)NULL,

                           const char *_host_name = (const char*)NULL,

                           const ::CORBA::BindOptions* _opt = (::CORBA::BindOptions*)NULL,

                           ::CORBA::ORB_ptr _orb = (::CORBA::ORB_ptr)NULL);

 

    static Hello_ptr _bind(const char *_poa_name,

                           const ::CORBA::OctetSequence& _id,

                           const char *_host_name = (const char*)NULL,

                           const ::CORBA::BindOptions* _opt = (::CORBA::BindOptions*)NULL,

                           ::CORBA::ORB_ptr _orb = (::CORBA::ORB_ptr)NULL);

 

in Hello_c.cpp, the _bind function are implemented as:

HelloApp::Hello *HelloApp::Hello::_bind(const char *_object_name,

                                        const char *_host_name,

                                        const ::CORBA::BindOptions *_opt,

                                        ::CORBA::ORB_ptr _orb)

{

  VISCLEAR_EXCEP

  ::CORBA::Object_var _obj = ::CORBA::Object::_bind_to_object("IDL:HelloApp/Hello:1.0",

_object_name, _host_name, _opt, _orb);

  return Hello::_narrow(_obj);

}

 

HelloApp::Hello *HelloApp::Hello::_bind(const char *_poa_name,

                                        const ::CORBA::OctetSequence& _id,

                                        const char *_host_name,

                                        const ::CORBA::BindOptions *_opt,

                                        ::CORBA::ORB_ptr _orb)

{

  VISCLEAR_EXCEP

  ::CORBA::Object_var _obj = ::CORBA::Object::_bind_to_object("IDL:HelloApp/Hello:1.0",

_poa_name, _id, _host_name, _opt, _orb);

  return Hello::_narrow(_obj);

}

 

as you can see the second _bind function definition in Hello_c.hh, just identical to the following snippet:

    static Hello_ptr _bind(const char *_poa_name,

                           const ::CORBA::OctetSequence& _id,

                           const char *_host_name = (const char*)NULL,

                           const ::CORBA::BindOptions* _opt = (::CORBA::BindOptions*)NULL,

                           ::CORBA::ORB_ptr _orb = (::CORBA::ORB_ptr)NULL);

the first two parameters must be provided, while the next three parameters are optional. HelloClient.c there are only the first 2 parameters were provided. I think the second form of _bind should be faster, especially in a quite large LAN.

 

3.       Servant implementation.

#include "Bank_s.hh"

#include <math.h>

 

// USE_STD_NS is a define setup by VisiBroker to use the std namespace

USE_STD_NS

 

// The AccountRegistry is a holder of Bank account implementations

class AccountRegistry

{

       public:

    AccountRegistry() : _count(0), _max(16), _data((Data*)NULL)

    {

             _data = new Data[16];

     }

 

    ~AccountRegistry() { delete[] _data; }

 

    void put(const char* name, PortableServer::ServantBase_ptr servant)

{

             if (_count + 1 == _max)

{

                    Data* oldData = _data;

                    _max += 16;

                    _data = new Data[_max];

                    for (CORBA::ULong i = 0; i < _count; i++)

                           _data[i] = oldData[i];

                    delete[] oldData;

             }

             _data[_count].name = name;

             servant->_add_ref();

             _data[_count].account = servant;

             _count++;

    }

 

PortableServer::ServantBase_ptr get(const char* name)

{

             for (CORBA::ULong i = 0; i < _count; i++)

{

                    if (strcmp(name, _data[i].name) == 0)

{

                           _data[i].account->_add_ref();

                           return _data[i].account;

                    }

             }

             return PortableServer::ServantBase::_nil();

    }

 

       private:

               struct Data

{

                      CORBA::String_var                name;

                      PortableServer::ServantBase_var  account;

               };

 

    CORBA::ULong _count;

    CORBA::ULong _max;

    Data*        _data;

};

 

 

class AccountImpl : public virtual POA_Bank::Account, public virtual PortableServer::RefCountServantBase

{

       public:

    AccountImpl(CORBA::Float balance) : _balance(balance)

    {}

 

    CORBA::Float balance() { return _balance; }

 

       private:

               CORBA::Float _balance;

};

 

 

class AccountManagerImpl : public POA_Bank::AccountManager

{

       public:

               AccountManagerImpl() {}

 

               Bank::Account_ptr open(const char* name) {

             // Lookup the account in the account dictionary.

             PortableServer::ServantBase_var servant = _accounts.get(name);

    

             if (servant == PortableServer::ServantBase::_nil())

{

                    // Make up the account's balance, between 0 and 1000 dollars.

                    CORBA::Float balance = abs(rand()) % 100000 / 100.0;

 

                    // Create the account implementation, given the balance.

                    servant = new AccountImpl(balance);

 

                    // Print out the new account

                    cout << "Created " << name << "'s account." << endl;

 

                    // Save the account in the account dictionary.

                    _accounts.put(name, servant);

             }

 

try
{

                    // Activate it on the default POA which is root POA for this servant

                    PortableServer::POA_var default_poa = _default_POA();

                    CORBA::Object_var ref = default_poa->servant_to_reference(servant);

                    Bank::Account_var account = Bank::Account::_narrow(ref);

 

                    // Print out the new account

                    cout << "Returning " << name << "'s account: " << account << endl;

 

                    // Return the account

                    return Bank::Account::_duplicate(account);

             }

             catch(const CORBA::Exception& e)

{

                    cerr << "_narrow caught exception: " << e << endl;

             }

             return Bank::Account::_nil();

    }

 

       private:

               AccountRegistry _accounts;

};

 

4.       Server

#include "BankImpl.h"

 

// USE_STD_NS is a define setup by VisiBroker to use the std namespace

USE_STD_NS

 

int main(int argc, char* const* argv)

{

       try

{

               // Initialize the ORB.

               CORBA::ORB_var orb = CORBA::ORB_init(argc, argv);

 

               // get a reference to the root POA

               CORBA::Object_var obj = orb->resolve_initial_references("RootPOA");

               PortableServer::POA_var rootPOA = PortableServer::POA::_narrow(obj);

   

               CORBA::PolicyList policies;

               policies.length(1);

               policies[(CORBA::ULong)0] = rootPOA->create_lifespan_policy(PortableServer::PERSISTENT);

 

               // get the POA Manager

               PortableServer::POAManager_var poa_manager = rootPOA->the_POAManager();

 

               // Create myPOA with the right policies

               PortableServer::POA_var myPOA = rootPOA->create_POA("bank_agent_poa",

                                                        poa_manager,

                                                        policies);

               // Create the servant

               AccountManagerImpl managerServant;

 

               // Decide on the ID for the servant

               PortableServer::ObjectId_var managerId =

                           PortableServer::string_to_ObjectId("BankManager"); //”BankManager” can be any uniqe string, but

                                                                                                                                                     the client side should be identical to it.

 

               // Activate the servant with the ID on myPOA

               myPOA->activate_object_with_id(managerId, &managerServant);

 

               // Activate the POA Manager

               poa_manager->activate();

 

               CORBA::Object_var reference = myPOA->servant_to_reference(&managerServant);

               cout << reference << " is ready" << endl;

 

               // Wait for incoming requests

               orb->run();

       }

       catch(const CORBA::Exception& e)

{

               cerr << e << endl;

               return 1;

       }

       return 0;

}

 

5.       Makefile.cpp

include ../stdmk_nt

 

EXE =      Client.exe Server.exe

 

all: $(EXE)

 

clean:

         del *.obj

         del *.exe

         del *_c.cpp

         del *_s.cpp

         del *.hh

#       del *.log                      //because never appeared on Windows Platform

#       del *.out                      //because never appeared on Windows Platform

#       del *.ilk                        //because never appeared on Windows Platform

#       del *.pdb                     //because never appeared on Windows Platform

 

#

# "Bank" specific make rules

#

 

Bank_c.cpp: Bank.idl

         $(ORBCC) Bank.idl

 

Bank_s.cpp: Bank.idl

         $(ORBCC) Bank.idl

 

Client.exe: Bank_c.obj Client.obj

         $(LINK_EXE) /out:Client.exe Client.obj /

         Bank_c.obj $(LIBORB) $(STDCC_LIBS)

 

Server.exe: Bank_s.obj Bank_c.obj Server.obj

         $(LINK_EXE) /out:Server.exe Server.obj /

         Bank_s.obj Bank_c.obj $(LIBORB) $(STDCC_LIBS)

6.       Build

Open a DOS window, and go to VC_Installed/bin, and run vcvars32.bat

Set environmental variable by SET VBROKERDIR=E:/BES if it is not set before, E:/BES is where the visibroker installed

Build all by run nmake –f Makefile.cpp.

 

Note: you can use nmake –f Makefile.cpp clean to clean all the files built before.

 

7.       Run the server by

prompt>Server

 

8.       Run the client by

prompt>Client

 

9.       Result:

Server side:

 

Fig. 3

Client side:

 

Fig. 4

++++++++++++++++++++++++++++ The end of exmaple ++++++++++++++++++++++++++++

 

后篇:Hands-on on VisiBroker5.1 for C++ and Java (2)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值