The mapping of Slice interfaces revolves around the idea that, to invoke a remote operation, you call a member function on a local class instance that is a proxy for the remote object. This makes the mapping easy and intuitive to use because making a remote procedure call is no different from making a local procedure call (apart from error semantics).
On this page:
Proxy Interfaces in MATLAB
A Slice interface maps to a MATLAB class with methods that correspond to the operations on that interface. Consider the following simple interface:
The Slice compiler generates the following definition for use by the client:
As you can see, the compiler generates a proxy class
SimplePrx. In general, the generated name is
<interface-name>Prx. If an interface is nested in a module
M, the generated class is part of package
M, so the fully-qualified name is
In the client's address space, an instance of
SimplePrx is the local ambassador for a remote instance of the
Simple interface in a server and is known as a proxy instance. All the details about the server-side object, such as its address, what protocol to use, and its object identity are encapsulated in that instance.
SimplePrx inherits from
ObjectPrx. This reflects the fact that all Ice interfaces implicitly inherit from
For each operation in the interface, the proxy class has a method of the same name. For the preceding example, we find that the operation
op has been mapped to the method
op. Notice that the
op method accepts a variable argument list. This allows you to specify an optional request context of type
containers.Map. This parameter is for use by the Ice run time to store information about how to deliver a request. You normally do not need to use it.
Proxy instances are always instantiated on behalf of the client by the Ice run time, so client code never has any need to instantiate a proxy directly.
An empty array denotes the null proxy. The null proxy is a dedicated value that indicates that a proxy points "nowhere" (denotes no object).
Interface Inheritance in MATLAB
Inheritance relationships among Slice interfaces are maintained in the generated MATLAB classes. For example:
The generated code for
CPrx reflects the inheritance hierarchy:
Given a proxy for
C, a client can invoke any operation defined for interface
C, as well as any operation inherited from
C's base interfaces.
ObjectPrx Interface in MATLAB
All Ice objects have
Object as the ultimate ancestor type, so all proxies inherit from
ObjectPrx provides a number of methods:
The methods behave as follows:
This method allows two proxies to be compared for equality using the
==operator. Note that all aspects of proxies are compared by this operation, such as the communication endpoints for the proxy. This means that, in general, if two proxies compare unequal, that does not imply that they denote different objects. For example, if two proxies denote the same Ice object via different transport endpoints,
falseeven though the proxies denote the same object.
This method returns the identity of the object denoted by the proxy. The identity of an Ice object has the following Slice type:
To see whether two proxies denote the same object, first obtain the identity for each object and then compare the identities:
ice_isAmethod determines whether the object denoted by the proxy supports a specific interface. The argument to
ice_isAis a type ID. For example, to see whether a proxy of type
Printerobject, we can write:
Note that we are testing whether the proxy is null before attempting to invoke the
ice_isAmethod. This avoids getting an error if the proxy is an empty array.
ice_idsmethod returns an array of strings representing all of the type IDs that the object denoted by the proxy supports.
ice_idmethod returns the type ID of the object denoted by the proxy. Note that the type returned is the type of the actual object, which may be more derived than the static type of the proxy. For example, if we have a proxy of type
BasePrx, with a static type ID of
::Base, the return value of
::Base, or it might something more derived, such as
ice_pingmethod provides a basic reachability test for the object. If the object can physically be contacted (that is, the object exists and its server is running and reachable), the call completes normally; otherwise, it throws an exception that indicates why the object could not be reached, such as
ice_ping methods are remote operations and therefore support an optional request context. Also note that there are other methods in
ObjectPrx, not shown here. These methods provide different ways to dispatch a call and also provide access to an object's facets.
Proxy Helper Methods in MATLAB
As we saw earlier, the Slice-to-MATLAB compiler generates static helper methods that support down-casting and type discovery:
checkedCast, if the passed proxy is for an object of type
Simple, or a proxy for an object with a type derived from
Simple, the cast returns a non-null reference to a proxy of type
SimplePrx; otherwise, if the passed proxy denotes an object of a different type (or if the passed proxy is null), the cast returns an empty array. You can optionally supply a facet and a request context, in that order; if you supply a request context, you must also supply a facet.
Given a proxy of any type, you can use a
checkedCast to determine whether the corresponding object supports a given type, for example:
Note that a
checkedCast contacts the server. This is necessary because only the implementation of an object in the server has definite knowledge of the type of an object. As a result, a
checkedCast may throw a
ConnectTimeoutException or an
In contrast, an
uncheckedCast does not contact the server and unconditionally returns a proxy of the requested type. However, if you do use an
uncheckedCast, you must be certain that the proxy really does support the type you are casting to; otherwise, if you get it wrong, you will most likely get a run-time exception when you invoke an operation on the proxy. The most likely error for such a type mismatch is
OperationNotExistException. However, other exceptions, such as a marshaling exception are possible as well. And, if the object happens to have an operation with the correct name, but different parameter types, no exception may be reported at all and you simply end up sending the invocation to an object of the wrong type; that object may do rather nonsensical things. To illustrate this, consider the following two interfaces:
Suppose you expect to receive a proxy for a
Process object and use an
uncheckedCast to down-cast the proxy:
If the proxy you received actually denotes a
Rocket object, the error will go undetected by the Ice run time: because
float have the same size and because the Ice protocol does not tag data with its type on the wire, the implementation of
Rocket::launch will simply misinterpret the passed integers as floating-point numbers.
In fairness, this example is somewhat contrived. For such a mistake to go unnoticed at run time, both objects must have an operation with the same name and, in addition, the run-time arguments passed to the operation must have a total marshaled size that matches the number of bytes that are expected by the unmarshaling code on the server side. In practice, this is extremely rare and an incorrect
uncheckedCast typically results in a run-time exception.
You may optionally supply a facet argument to
Another method generated for every interface is
ice_staticId, which returns the type ID string corresponding to the interface. As an example, for the Slice interface
Simple in module
M, the string returned by
Using Proxy Methods in MATLAB
The base proxy class
ObjectPrx supports a variety of methods for customizing a proxy. Since proxies are immutable, each of these "factory methods" returns a copy of the original proxy that contains the desired modification. For example, you can obtain a proxy configured with a ten second invocation timeout as shown below:
A factory method returns a new proxy object if the requested modification differs from the current proxy, otherwise it returns the current proxy. With few exceptions, factory methods return a proxy of the same type as the current proxy, therefore it is generally not necessary to repeat a
uncheckedCast after using a factory method. Furthermore, the mapping generates type-specific factory methods so that no casts are necessary:
The only exceptions are the factory methods
ice_identity. Calls to either of these methods may produce a proxy for an object of an unrelated type, therefore they return a base proxy that you must subsequently down-cast to an appropriate type using
Object Identity and Proxy Comparison in MATLAB
Proxies can be compared for equality using the
== operator. Note that proxy comparison with
== uses all of the information in a proxy for the comparison. This means that not only the object identity must match for a comparison to succeed, but other details inside the proxy, such as the protocol and endpoint information, must be the same. In other words, comparison with
== tests for proxy identity, not object identity. A common mistake is to write code along the following lines:
proxy2 differ, they may still denote the same Ice object. This can happen because, for example, both
proxy2 embed the same object identity, but each use a different protocol to contact the target object. Similarly, the protocols may be the same, but denote different endpoints (because a single Ice object can be contacted via several different transport endpoints). In other words, if two proxies compare equal with
equals, we know that the two proxies denote the same object (because they are identical in all respects); however, if two proxies compare unequal with
equals, we know absolutely nothing: the proxies may or may not denote the same object.
To compare the object identities of two proxies, you can use helper functions in the
proxyIdentityCompare allows you to correctly compare proxies for identity:
The function returns 0 if the identities are equal,
p1 is less than
p2, and 1 if
p1 is greater than
p2. (The comparison uses
name as the major and
category as the minor sort key.)
proxyIdentityAndFacetCompare function behaves similarly, but compares both the identity and the facet name.