www.delorie.com/gnu/docs/smalltalk/gst_33.html   search  
Buy GNU books!

GNU Smalltalk User's Guide

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

3.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 your module. If you are writing an external Smalltalk module (which can look at Smalltalk objects and manipulate them), see Linking your libraries to the virtual machine; if you are using function from a dynamically loaded library, see 2.6 Dynamic loading.

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 `kernel/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:

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@sc{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:
Single C character value

A C char *, converted to a Smalltalk string

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

A C char *, converted to a Smalltalk symbol

A C int value

A C unsigned int value

A C long value

A C unsigned long value

A C double, converted to an instance of FloatD

No returned value

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

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 3.4 Manipulating Smalltalk data from C).

You can pass an instance of CType or one of its subclasses (see section 3.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.

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

passed as char, which is promoted to int

passed as char, which is promoted to int

passed as char *

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

passed as char *

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

passed as int

passed as unsigned int

passed as long

passed as unsigned long

passed as double

C object value passed as long or void *

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.

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.

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

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

  webmaster     delorie software   privacy  
  Copyright 2003   by The Free Software Foundation     Updated Jun 2003