Navigation:  Programming Cookbook > External Interfacing > External Methods >

External Method Format

Previous pageReturn to chapter overviewNext page

The format of an external call method is similar to a primitive method. External call methods have the usual method header – a keyword selector with interspersed argument names. In order to standardise the names of external library selectors (and thus make them both easier to find and less likely to be duplicated), we follow the External Method Selector pattern. This pattern is based on the CORBA Smalltalk mapping name generation scheme.

Following the method header is the external call descriptor:

< <call type> <return type> <descriptor> <parm list> >

 

where:

<call type> = [virtual] <call convention>

<call convention> = stdcall: | cdecl:

<descriptor> = <virtual function number> | <proc name>

<vfn number> = 1..n

<proc name> = <ordinal no.> | <literal symbol or quoted string>

<parm list> = <parm type> | <parm type> <parm list>

<parm type> = <struct type>[*] | dword | sdword | word | sword | lpvoid |

       lppvoid | char | byte | sbyte | bool | handle | float | double |

       lpstr | lpwstr | hresult | qword | sqword | varbool | variant |

       bstr | guid

<return type> = void | <parm type>

<struct type> = ExternalStructure subclass name

 

The virtual prefix and virtual function number are only for use when constructing virtual calls.

The parameter list must contain as many parameters as are passed to the method, plus one for the return type from the external function (the return of which will form the return from the primitive invocation method).

In the case of a call to the Win32 GetComputerName() function a suitable method (of KernelLibrary) might be:

getComputerName: buffer nSize: pBufSize

  "    BOOL GetComputerName(

          LPTSTR lpBuffer,    // address of name buffer

          LPDWORD nSize         // address of size of lpBuffer

      );"

  <stdcall: bool GetComputerNameA lpstr DWORD* >

  ^self invalidCall

 

This function is wrapped by SessionManager>>computerName, as follows:

computerName

  "Answer the name of the computer hosting the current session.

  Signals a HostSystemError if the request fails."

  | name nameSize |

  name := String new: MAX_COMPUTERNAME_LENGTH.

  nameSize := DWORD fromInteger: name size+1.

  (KernelLibrary default getComputerName: name nSize: nameSize asParameter)

      ifFalse: [HostSystemError signal].

  ^name leftString: nameSize asInteger