Back: External modules
Up: C and Smalltalk
Forward: C data types
 
Top: GNU Smalltalk User's Guide
Contents: Table of Contents
Index: Class index
About: About this document

4.2 Using the C callout mechanism

To use the C callout mechanism, you first need to inform Smalltalk about the C functions that you wish to call. You currently need to do this in two places: 1) you need to establish the mapping between your C function's address and the name that you wish to refer to it by, and 2) define that function along with how the argument objects should be mapped to C data types to the Smalltalk interpreter. As an example, let us use the pre-defined (to GNU Smalltalk) functions of system and getenv.

First, the mapping between these functions and string names for the functions needs to be established in `cint.c'. In the function initCFuncs, the following code appears:
 
extern int system();
extern char *getenv();

defineCFunc("system", system);
defineCFunc("getenv", getenv);

Any functions that you will call from Smalltalk must be similarly defined.

Second, we need to define a method that will invoke these C functions and describe its arguments to the Smalltalk runtime system. Such a method is automatically generated by calling a method which is available to every class, defineCFunc:withSelectorArgs:returning:args:. The method that was used in old versions of GNU Smalltalk, defineCFunc:withSelectorArgs:forClass:returning:args:, is still present for backward compatibility, but its use is deprecated and should be avoided.

Here are the definitions for the two functions system and getenv (taken from `CFuncs.st')
 
SystemDictionary defineCFunc: 'system'
    withSelectorArgs: 'system: aString'
    returning: #int
    args: #(#string)!

SystemDictionary defineCFunc: 'getenv'
    withSelectorArgs: 'getenv: aString'
    returning: #string
    args: #(#string)!

The various keyword arguments are described below.

The arguments are as follows:

SystemDictionary
This specifies where the new method should be stored. In our case, the method will be installed in the SystemDictionary, so that we would invoke it thus:
 
   Smalltalk system: 'lpr README' !

Again, there is no special significance to which class receives the method; it could have just as well been Float, but it might look kind of strange to see:
 
   1701.0 system: 'mail sbb@gnu.org' !

defineCFunc: 'system'
This says that we are defining the C function system. This name must be exactly the same as the string passed to defineCFunc.

withSelectorArgs: 'system: aString'
This defines how this method will be invoked from Smalltalk. The name of the method does not have to match the name of the C function; we could have just as easily defined the selector to be 'rambo: fooFoo'; it's just good practice to define the method with a similar name and the argument names to reflect the data types that should be passed.

returning: #int
This defines the C data type that will be returned. It is converted to the corresponding Smalltalk data type. The set of legal return types is:
char
Single C character value

string
A C char *, converted to a Smalltalk string

stringOut
A C char *, converted to a Smalltalk string and then freed.

symbol
A C char *, converted to a Smalltalk symbol

int
A C int value

uInt
A C unsigned int value

long
A C long value

uLong
A C unsigned long value

double
A C double, converted to an instance of Float

void
No returned value

cObject
An anonymous C pointer; useful to pass back to some C function later

smalltalk
An anonymous (to C) Smalltalk object pointer; should have been passed to C at some point in the past or created by the program by calling other public GNU Smalltalk functions (see section 4.4 Manipulating Smalltalk data from C).

ctype
You can pass an instance of CType or one of its subclasses (see section 4.3 The C data type manipulation system)

args: #(#string)
This is an array of symbols that describes the types of the arguments in order. For example, to specify a call to open(2), the arguments might look something like:
 
   args: #(#string #int #int)

The following argument types are supported; see above for details.

unknown
Smalltalk will make the best conversion that it can guess for this object; see the mapping table below

boolean
passed as char, which is promoted to int

char
passed as char, which is promoted to int

string
passed as char *

stringOut
passed as char *, the contents are expected to be overwritten with a new C string, and the object that was passed becomes the new string on return

symbol
passed as char *

byteArray
passed as char *, even though may contain NUL's

int
passed as int

uInt
passed as unsigned int

long
passed as long

uLong
passed as unsigned long

double
passed as double

cObject
C object value passed as long or void *

smalltalk
Pass the object pointer to C. The C routine should treat the value as a pointer to anonymous storage. This pointer can be returned to Smalltalk at some later point in time.

variadic
variadicSmalltalk
an Array is expected, each of the elements of the array will be converted like an unknown parameter if variadic is used, or passed as a raw object pointer for variadicSmalltalk.

self
selfSmalltalk
Pass the receiver, converting it to C like an unknown parameter if self is used or passing the raw object pointer for selfSmalltalk. Parameters passed this way don't map to the message's arguments, instead they map to the message's receiver.

Table of parameter conversions:

Declared param type Object type C parameter type used
boolean Boolean (True, False) int
byteArray ByteArray char *
cObject CObject void *
char Boolean (True, False) int
char Character int (C promotion rule)
char Integer int
double Float double (C promotion)
int Boolean (True, False) int
int Integer int
uInt Boolean (True, False) unsigned int
uInt Integer unsigned int
long Boolean (True, False) long
long Integer long
uLong Boolean (True, False) unsigned long
uLong Integer unsigned long
smalltalk, selfSmalltalk anything OOP
string String char *
string Symbol char *
stringOut String char *
symbol Symbol char *
unknown, self Boolean (True, False) int
unknown, self ByteArray char *
unknown, self CObject void *
unknown, self Character int
unknown, self Float double
unknown, self Integer long
unknown, self String char *
unknown, self Symbol char *
unknown, self anything else OOP
variadic Array each element is passed according to "unknown"
variadicSmalltalk Array each element is passed as an OOP




This document was generated on May, 12 2002 using texi2html