Skip to main content
Skip table of contents

Client-Side C++ Mapping for Operations

Mapping for Operations

As we saw in the Client-Side C++ Mapping for Interfaces, for each operation on an interface, the generated proxy class contains 3 member functions for this operation. To invoke an operation, you call one of these functions on the proxy. For example, let’s take the generated code from the greeter example:

SLICE
module VisitorCenter
{
    interface Greeter
    {
        string greet(string name);
    }
}

The proxy class generated from the Greeter interface, after removing extra details, is as follows:

CPP
namespace VisitorCenter
{
    class GreeterPrx : public Ice::Proxy<GreeterPrx, Ice::ObjectPrx>
    {
    public:
        GreeterPrx(const Ice::CommunicatorPtr& communicator,
                std::string_view proxyString);

        // ...

        std::string greet(std::string_view name,
                const Ice::Context& context = Ice::noExplicitContext) const;

        std::future<std::string> greetAsync(std::string_view name,
                const Ice::Context& context = Ice::noExplicitContext) const;

        std::function<void()> greetAsync(std::string_view name,
                std::function<void(std::string)> response,
                std::function<void(std::exception_ptr)> exception = nullptr,
                std::function<void(bool)> sent = nullptr,
                const Ice::Context& context = Ice::noExplicitContext) const;

        // ...
    };
}

Given a proxy to an object of type Greeter, the client can invoke the greet operation as follows:

CPP
GreeterPrx greeter{communicator, "greeter:tcp -h localhost -p 4061"};
string greeting = greeter.greet("Alice");  // Get greeting via RPC

This code calls greet on the proxy class instance, which sends the request to the server, waits until the operation is complete, and then unmarshals the return value and returns it to the caller.

Because the return value is of type string, it is safe to ignore the return value. For example, the following code contains no memory leak:

CPP
GreeterPrx greeter{communicator, "greeter:tcp -h localhost -p 4061"};
greeter.greet("Alice");  // Useless, but no leak

This is true for all mapped Slice types: you can safely ignore the return value of an operation, no matter what its type — return values are always returned by value. If you ignore the return value, no memory leak occurs because the destructor of the returned value takes care of deallocating memory as needed.

Sync and Async Functions

For each operation, the Slice compiler generates 3 member functions on the proxy class:

  • one “sync” function with the same name as the operation. When you call this function, your thread waits synchronously until the invocation completes. A successful invocation completes with a return value (which can be void), while an unsuccessful invocation completes with an exception.

  • two overloaded “async” functions, named <operation-name>Async. When you call these functions, your thread marshals the arguments to the function synchronously, but the remainder of this invocation is asynchronous, and the function returns immediately. You get the result (return value or exception) through an std::future or a callback depending on the async overload you selected. These async functions are described in more detail in Asynchronous Method Invocation (AMI) in C++.

Async invocations allow you to use threads more efficiently. Sync invocations are more convenient to call. You decide what’s more important for your application.

Exception Handling

Any operation invocation may throw a runtime exception and, if the operation has an exception specification, may also throw user exceptions. Suppose we have the following simple interface:

SLICE
exception Tantrum
{
    string reason;
}

interface Child
{
    void askToCleanUp() throws Tantrum;
}

Slice exceptions are thrown as C++ exceptions, so you can simply enclose one or more operation invocations in a try-catch block:

CPP
ChildPrx child = ...;           // Get Child proxy...
try
{
    child.askToCleanUp();      // Give it a try...
} 
catch (const Tantrum& t)
{
    cout << "The child says: " << t.reason << endl;
}
See Also
JavaScript errors detected

Please note, these errors can depend on your browser setup.

If this problem persists, please contact our support.