Next: Errors, Previous: Variable method arguments, Up: Methods [Index]
Occasionally an application needs to call a method as a function. One
example of this is a SignalHandler
method that the program
installs as the handler for signals from the operating system.
Methods that use a C calling convention need to do several things differently than normal methods.
In order to make Ctalk interpret a method parameter as a C variable, the
method must declare the parameter with the __c_arg__
attribute.
Note: C functions that are called by the operating system
generally need only one argument, and the __c_arg__
attribute
only works for methods with a single parameter.
Additionally, to prevent Ctalk from adding local object initialization
code to the method, the method must contain the noMethodInit
keyword.
Here is an example of a method that is used as a signal handler, and
installed by the statements in main.
SignalHandler instanceMethod myHandler (__c_arg__ int signo) { noMethodInit; printf ("sigInt handler! Signal %d.\n", signo); return NULL; } int main () { SignalHandler new s; s setSigInt; s installHandler myHandler; }
The setSigInt
method (class SignalHandler
) tells the
SignalHandler
object s
that it is going to handle
SIGINT
signals. See SignalHandler, for the other signals
that the class can handle.
The __ctalkNewSignalEventInternal
function can generate and
queue SignalEvent
objects, so the signal handler does not need
to create objects in order to send signal events to the application.
See __ctalkNewSignalEventInternal.
Often you will need to use C functions and data types in method functions. However, you need to take care that if you include a C header file, it might not be included later on if a class library requires that file.
Normally Ctalk includes whatever C definitions it needs in the class libraries. However, that can cause the preprocessor to omit those definitions from another source file, should the definitions be needed later.
For example, in the method handleSignal
, from the
timeclient.c
program, the method needs the definition
of the time(2) function. If you were to #include
time.h
in the input, as in this example, then time.h
’s
definitions would not be included in the CTime
class later on.
#include <time.h> /* Could cause errors later. */ SignalHandler instanceMethod handleSignal (__c_arg__ int signo) { time_t t; char buf[MAXLABEL]; noMethodInit; t = time (NULL); __ctalkDecimalIntegerToASCII (t, buf); __ctalkNewSignalEventInternal (signo, getpid (), buf); return NULL; }
The best way to avoid omitting dependencies is to include only the definitions that the method needs. In this case, you can include the prototype of time(2) in the source file.
extern time_t time (time_t *__timer) __THROW; /* From time.h. */ SignalHandler instanceMethod handleSignal (__c_arg__ int signo) { time_t t; char buf[MAXLABEL]; noMethodInit; t = time (NULL); __ctalkDecimalIntegerToASCII (t, buf); __ctalkNewSignalEventInternal (signo, getpid (), buf); return NULL; }
The time_t
type is defined with ctalklib
, and is
available to all programs.
How to resolve multiple library definitions depends on the system’s header files, and may vary between different operating systems or compiler versions.
Next: Errors, Previous: Variable method arguments, Up: Methods [Index]