There is no standard specification for IDL to Objective C mapping. ADORB uses the IDL mapping that is defined below.
The IDL types are mapped into Objective C types differently depending on whether the type is used directly as a operation's argument or the type is contained in another container type: struct, union, array, sequence, or valuetype. In the latter case a wrapper class for this type is used.
IDL type | Objective C type (class) | Objective C wrapper class |
---|---|---|
char | unsigned char | NSNumber |
unsigned char | unsigned char | NSNumber |
wchar | unsigned short | NSNumber |
short | short | NSNumber |
unsigned short | unsigned short | NSNumber |
long | long | NSNumber |
unsigned long | unsigned long | NSNumber |
long long | long long | NSNumber |
unsigned long long | unsigned long long | NSNumber |
float | float | NSNumber |
double | double | NSNumber |
boolean | BOOL | NSNumber |
octet | unsigned char | NSNumber 3) |
octet [ ] | NSData | |
sequence <octet> | NSData | |
string | NSString | |
wstring | NSString | |
struct | IDLObject 2) | |
union | NSDictionary 2) | |
sequence <type> | NSArray 1) | |
type [ ] | NSArray 1) | |
Object | CORBAObject | |
any | IDLAnyObject 2) | |
exception | NSException | |
interface | Protocol | |
abstract interface | NSObject or Protocol | |
fixed | Not implemented | |
valuetype | IDLObject 2) | |
valuebox | class for the boxed type | |
AbstractBase | IDLObject or Protocol | |
ValueBase | IDLObject |
#pragma class
preprocessor directive. Since ADORB uses NSKeyValueCoding protocol for marshaling and un-marshaling data the instances of any class can be used for the in and inout arguments. Specifying the class in #pragma class
provides un-marshaling the returned values into an instance of the given class. ADORB uses the - initWithIDLType:
or - init
method to create an instance of the class and the - setValue:forKey:
and - valueForKey:
methods to set and get instance variables accordingly.On the server the wrapper class may be used for an argument since the method signature is available and framework can convert arguments to the required type.
struct
typeThe struct
type is mapped into IDLObject class. If the #pragma class
directive defines a class for an IDL struct then that class should define the corresponding instance variables or the accessor methods.
For example, the following IDL struct
struct Customer { long customerId; string customerName; }; #pragma class Customer MyCustomercan be mapped to the Objective C class
@interface MyCustomer : NSObject { long _customerId; NSString* _customerName; } @end
union
typeThe union
type is mapped to NSDictionary
with two keys:
descriptor
- for the union's descriptor valuevalue
- for the union's case valueIf the #pragma class
directive defines a class for an IDL union then that class should define the corresponding instance variables or the accessor methods. For example:
@interface MyUnion : NSObject { NSNumber* _descriptor; id _value; } . . . - (void) setValue:value; . . . @end
any
typeThe any
type is mapped to IDLAnyObject
.
If the #pragma class
directive defines a different class for the any
type then that class should define the appropriate instance variables or the accessor methods (see NSKeyValueCoding protocol in the Foundation framework for details).
For example, for the following IDL definition
module CosNaming { typedef string Istring; struct NameComponent { Istring id; Istring kind; }; void foo(any name); };we can write the code
CORBAObject* server; // assume it exists ... id type = [[ORB defaultORB]definitionNamed:@"CosNaming/NameComponent"]; NSDictionary* name = [NSDictionary dictionaryWithObjectsAndKeys: @"some-name", @"id", @"some-ext", @"kind", nil]; IDLAnyObject* arg = [IDLAnyObject objectWithIDLType:type]; [arg setValue:name]; [server foo:arg];
valuetype
typeThe #pragma class
allows to define arbitrary Objective C class to map the valuetype
to. The class should define the appropriate instance variables or access methods. Different valuetypes can be mapped to the same class. If no object class is set for the valuetype
it is mapped to IDLObject with the keys corresponding to the valuetype
member names. See IDLValueType class for detailed description.
valuebox
typeThe vauluebox
is a particular case of valuetype
. The value is mapped as defined by the boxed type. The wrapper class is used for the primitive types.
For example, if we have:
valuetype VDouble double; VDouble echo_double(in VDouble value);we can write the code
CORBAObject* server; .... NSNumber* value = [NSNumber numberWithDouble:2.718]; // The object of the wrapper class (NSNumber) is used as the argument and the return value // The nil value may be send or returned NSNumber* result = [server echoDouble:value];
IDL operations (functions) are mapped into Objective C methods. ADORB creates two method selectors for each operation.
The first method selector is evaluated from the operation definition in the following way:
context
then the selector is padded by context:
in the case the operation has one or more arguments. If the operation has no arguments then the selector is padded by colon ':'.
The following table provides the examples of the Objective C method signatures for the IDL operation definitions from the CosNaming module:
IDL definition | Objective C method signature |
---|---|
NamingContext new_context(); | - (id<NamingContext>) newContext; |
Object resolve (in Name name ); | - resolve:(NSArray*)name; |
void rebind_context (in Name name, in NamingContext naming_context ); | - (void) rebindContext:(NSArray*)name namingContext:(id<NamingContext>)naming_context; |
void set_value(in string value) context("ctx"); | - (void) setValue:(NSString*)value context:context; |
string get_value() context("ctx"); | - (NSStrng*) getValue:context; |
These method signatures depend on the argument names in the IDL definitions, which are not persistent.
AdORB introduces a #pragma selector
preprocessor directive that allows to specify an Objective-C selector for an IDL operation.
A header file for a particular interface can be generated in the IDLBrowser application.
In the client the method call must match the method signature because the compiler does not leave any information about passed arguments and expected return value, and thus ADORB cannot verify the arguments and return value types. Besides, if an argument or return value size is greater than 4, or there are aguments of type float
the method prototype must be provided. The Objective C compiler allows to have no method prototypes and this may lead to incorrect results.
In the server the method signature and the types of the being passed arguments are available, so ADORB can convert the being passed arguments and the return value to the required type, if the method signature does not match the IDL definition.
The IDL exceptions are mapped into the instances of the NSException
class with the userInfo dictionary populated according to the IDL exception's definition.
If a client receives an exception in response for a request, the instance of NSException is created and raised. The client is responsible for handling this exception.
In a server, to return an exception back to client an instance of NSException should be created, initialized and raised.
ADORB introduces the #pragma class
directive that defines which class to use when un-marshaling a container type for the out and inout function arguments. Since ADORB uses KeyValue Coding when marshaling the in and inout arguments these arguments may be instances of any class when passed in the method call.
The format of the directive is
#pragma class definition-name class-name
The directive should be put after the end of the definition.
For example:
typedef string Istring; struct NameComponent { Istring id; Istring kind; }; #pragma class NameComponent MyNameComponent #pragma class any MyAny
If the class named class-name cannot be found then NSMutableDictionary class is used. The class name can also be set programmatically using the -setObjectClassName:
method.
ADORB introduces #pragma selector
directive that allows to specify Objective-C selector for a particular IDL operation.
The format of the directive is
#pragma selector operation-name objc-selector
The directive should be put within the interface where the operation is defined, after the operation definition.
For example:
interface NamingContext { ... exception InvalidName{}; exception AlreadyBound {}; exception NotEmpty{}; void bind(in Name n, in Object object) raises (NotFound, CannotProceed, InvalidName, AlreadyBound); void rebind (in Name n, in Object object) raises (NotFound, CannotProceed, InvalidName); #pragma selector bind bindName:toObject: #pragma selector rebind rebindName:toObject: }
ADORB supports the following preprocessor directives
#pragma class #pragme map (same as #pragma class) #pragma selector #pragma version #pragma prefix #pragma ID (sets typeID) #define #ifdef #ifndef #else #endif #include #import
ADORB IDL parser defines __ADORB__
macro which may be used in the preprocessor directives in the IDL files.