Your class implementation must include the companion “define” macro,
OSDefineMetaClassAndStructors. This macro defines the constructor and destructor, implements
the OSMetaClass allocation member function (alloc) for the class, and supplies the metaclass
information for the runtime typing system. OSDefineMetaClassAndStructors takes as arguments
the name of your driver’s class and the name of its base class. It uses these to generate code that allows
your driver class to be loaded and instantiated while the kernel is running. It typically occurs as one
of the first statements of the class implementation. For example, MyDriver.cpp might begin like this:
#include "MyDriver.h"
// This convention makes it easy to invoke base class member functions.
#define super IOService
// You cannot use the "super" macro here, however, with the
// OSDefineMetaClassAndStructors macro.
OSDefineMetaClassAndStructors(com_MyCompany_driver_MyDriver, IOService);
If the class you are defining is an abstract class intended only to be inherited from, use the
OSDeclareAbstractStructors and OSDefineMetaClassAndAbstractStructors macros instead.
These macros do the same things as their non-abstract counterparts except that they make the primary
constructor private and define the alloc member function to return zero.
The OSDefineMetaClassAndStructors and OSDefineMetaClassAndAbstractStructorsmacros are
based on two other OSMetaClass macros: OSDefineMetaClassAndStructorsWithInit and
OSDefineMetaClassAndAbstractStructorsWithInit, respectively. These latter two macros are
deprecated and should not be used directly.
Allocating Objects Dynamically
The OSMetaClass plays an important role in the libkern C++ runtime by allocating objects based
upon class type. Derived classes of OSMetaClass can do this dynamically by implementing the
allocfunction; the class type is supplied by the OSMetaClass derived class itself. As mentioned in
the previous section, "Object Scope and Constructor Invocation" (page 19), the constructors created
by the OSMetaClass macros implement alloc automatically for your class.
The container classes of libkern and the families of the I/O Kit provide various helper member
functions for creating (allocating) objects, and these are what you use most of the time. But you can
also directly allocate an instance of any libkern or I/O Kit class using two kinds of OSMetaClass calls:
■
By calling one of the OSMetaClass allocClassWithNamefunctions, supplying an identification
of class type (as an OSSymbol, OSString, or C-string)
■
By calling the macro OSTypeAlloc (defined in the OSMetaClassBase class)
Both the allocClassWithName and the OSTypeAlloc macro are similar in that they take some indication
of type as the sole argument. However, there is an important difference. Because of a preprocessor
artifact, the macro takes a type argument that is a compile-time symbol and not a string; thus the
macro is more efficient than the dynamic allocation performed by the allocClassWithName member
functions, but it is not truly dynamic. The allocation member functions defer binding until runtime,
whereas the macro will generate a link-time error if the kernel extension doesn’t properly specify the
dependencies of the type argument. In addition, the macro, unlike the functions, casts the result to
the appropriate type for you.
18
Object Creation and Destruction
2007-03-06 | © 2002, 2007 Apple Inc. All Rights Reserved.
CHAPTER 1
The libkern C++ Runtime