The GNU Objective-C runtime provides a hook, called
__objc_msg_forward2
, which is called by
objc_msg_lookup()
when it can’t find a method implementation in
the runtime tables and after calling +resolveInstanceMethod:
and +resolveClassMethod:
has been attempted and did not succeed
in dynamically registering the method.
To configure the hook, you set the global variable
__objc_msg_forward2
to a function with the same argument and
return types of objc_msg_lookup()
. When
objc_msg_lookup()
can not find a method implementation, it
invokes the hook function you provided to get a method implementation
to return. So, in practice __objc_msg_forward2
allows you to
extend objc_msg_lookup()
by adding some custom code that is
called to do a further lookup when no standard method implementation
can be found using the normal lookup.
This hook is generally reserved for “Foundation” libraries such as
GNUstep Base, which use it to implement their high-level method
forwarding API, typically based around the forwardInvocation:
method. So, unless you are implementing your own “Foundation”
library, you should not set this hook.
In a typical forwarding implementation, the __objc_msg_forward2
hook function determines the argument and return type of the method
that is being looked up, and then creates a function that takes these
arguments and has that return type, and returns it to the caller.
Creating this function is non-trivial and is typically performed using
a dedicated library such as libffi
.
The forwarding method implementation thus created is returned by
objc_msg_lookup()
and is executed as if it was a normal method
implementation. When the forwarding method implementation is called,
it is usually expected to pack all arguments into some sort of object
(typically, an NSInvocation
in a “Foundation” library), and
hand it over to the programmer (forwardInvocation:
) who is then
allowed to manipulate the method invocation using a high-level API
provided by the “Foundation” library. For example, the programmer
may want to examine the method invocation arguments and name and
potentially change them before forwarding the method invocation to one
or more local objects (performInvocation:
) or even to remote
objects (by using Distributed Objects or some other mechanism). When
all this completes, the return value is passed back and must be
returned correctly to the original caller.
Note that the GNU Objective-C runtime currently provides no support
for method forwarding or method invocations other than the
__objc_msg_forward2
hook.
If the forwarding hook does not exist or returns NULL
, the
runtime currently attempts forwarding using an older, deprecated API,
and if that fails, it aborts the program. In future versions of the
GNU Objective-C runtime, the runtime will immediately abort.