eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'ExternalLibraryFunction':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: ExternalLibraryFunction


Inheritance:

   Object
   |
   +--ExecutableFunction
      |
      +--ExternalFunction
         |
         +--ExternalLibraryFunction

Package:
stx:libbasic
Category:
System-Support
Version:
rev: 1.165 date: 2018/05/11 11:52:50
user: stefan
file: ExternalLibraryFunction.st directory: libbasic
module: stx stc-classLibrary: libbasic

Description:


instances of me are used to interface to external library functions (as found in a dll/shared object).
Foreign function calls are based on the FFI library if available.
A limited fallback implementation is provided for systems with no libffi.
(this may have limitations on the supported argument types; for example,
 the x86_64 fallback does not support float/double arguments).
Therefore the fallback should be considered a temporary workaround,
until libffi has been ported.

Inside a method, when a special external-call pragma such as:
    <api: bool MessageBeep(uint)>

is encountered by the parser, the compiler generates a call via
    <correspondingExternalLibraryFunctionObject> invokeWithArguments: argumentArray.
and the correspondingExternalLibraryFunctionObject is kept in the literal array.

In the invoke method, the library is checked to be loaded (and loaded if not already),
the arguments are converted to C and pushed onto the C-stack, the function is called,
and finally, the return value is converted back from C to a smalltalk object.

The parser supports the call-syntax of various other smalltalk dialects:
    Squeak / ST-X:
        <cdecl:   [async] [virtual|nonVirtual][const] returnType functionNameStringOrIndex ( argType1..argTypeN ) module: moduleName >
        <apicall: [async] [virtual|nonVirtual][const] returnType functionNameStringOrIndex ( argType1..argTypeN ) module: moduleName >

    Dolphin:
        <stdcall: [virtual|nonVirtual][const] returnType functionNameStringOrIndex argType1..argTypeN>
        <cdecl:   [virtual|nonVirtual][const] returnType functionNameStringOrIndex argType1..argTypeN>

    ST/V:
        <api: functionName argType1 .. argTypeN returnType>
        <ccall: functionName argType1 .. argTypeN returnType>
        <ole: vFunctionIndex argType1 .. argTypeN returnType>

    VisualWorks:
        <c: ...>
        <c: #define NAME value>


Class protocol:

class initialization
o  addToDllPath: aDirectoryPathName
can be used during initialization, to add more places for dll-loading
usage example(s):
     self addToDllPath:'c:\matrix\API\dll'

o  defaultDLLPath
return a default dll-path, as per operating system
usage example(s):
     self defaultDLLPath

o  dllMapping
allows for dll's to be replaced,
for example, if you want to use the mozilla sqlite dll
C:\Program Files\Mozilla Firefox\mozsqlite3.dll
for the sqlite3, execute:
ExternalLibraryFunction
dllMapping at:'sqlite3'
put: 'C:\Program Files\Mozilla Firefox\mozsqlite3.dll'
for mingw:
ExternalLibraryFunction
dllMapping at:'sqlite3'
put:'C:\mingw64\opt\bin\libsqlite3-0.dll'

o  dllMapping: aDictionary
allows for dll's to be replaced,
for example, if you want to use the mozilla sqlite dll
C:\Program Files\Mozilla Firefox\mozsqlite3.dll
for the sqlite3, execute:
ExternalLibraryFunction
dllMapping at:'sqlite3'
put: 'C:\Program Files\Mozilla Firefox\mozsqlite3.dll'
for mingw:
ExternalLibraryFunction
dllMapping at:'sqlite3'
put:'C:\mingw64\opt\bin\libsqlite3-0.dll'

o  dllMappingAt: baseLibname put: aNameOrPath
allows for dll's to be replaced,
for example, if you want to use the mozilla sqlite dll
C:\Program Files\Mozilla Firefox\mozsqlite3.dll
for the sqlite3, execute:
ExternalLibraryFunction
dllMappingAt:'sqlite3'
put: 'C:\Program Files\Mozilla Firefox\mozsqlite3.dll'
for mingw:
ExternalLibraryFunction
dllMappingAt:'sqlite3'
put:'C:\mingw64\opt\bin\libsqlite3-0.dll'

o  dllPath
provide a default dllPath, where external libraries are searched for
usage example(s):
     ExternalLibraryFunction dllPath

o  dllPath: aCollectionOfDirectoryPathNames
provide a default dllPath, where external libraries are searched for

o  flushModuleHandlesForLibrary: aLibraryName
self flushModuleHandlesForLibrary:'ole32.dll'

o  flushModuleHandlesForWhich: aBlock
self flushModuleHandlesForLibrary:'ole32.dll'

o  initialize
using inline access to corresponding c--defines to avoid duplicate places of knowledge
usage example(s):
DLLPATH := nil.
     self initialize

o  removeFromDllPath: aDirectoryPathName
remove added places from dll-loading
usage example(s):
     self dllPath.
     self addToDllPath:'C:\aaa\bbb'.
     self dllPath.
     self removeFromDllPath:'C:\aaa\bbb'.
     self dllPath.

constants
o  callTypeAPI

o  callTypeC

o  callTypeCDecl

o  callTypeMASK

o  callTypeOLE

o  callTypeUNIX64

debugging
o  verbose: aBoolean
turn on/off tracing of calls
usage example(s):
     ExternalLibraryFunction verbose:true

instance creation
o  name: functionName module: moduleName returnType: returnType argumentTypes: argTypes

type name mapping
o  ffiTypeSymbolForType: aType
map aType to one of the ffi-supported ones:
sint8, sint16, sint32, sint64
uint8, uint16, uint32, uint64
long ulong int uint
bool float double void pointer handle


Instance protocol:

accessing
o  argumentTypes

o  argumentTypesString

o  beAsync
let this execute in a separate thread, in par with the other execution thread(s).
Ignored under unix/linux (until those support multiple threads too).

o  beCallTypeAPI

o  beCallTypeC

o  beCallTypeOLE

o  beCallTypeUNIX64

o  beCallTypeV8

o  beCallTypeV9

o  beCallTypeWINAPI

o  beConstReturnValue
specify that a pointer return value is not to be finalized
(i.e. points to static data or data which is freed by c)

o  beMustFreeReturnValue
specify that a pointer return value is to be freed explicitly by st/x
(i.e. points to mallocd data which is not freed by c)

o  beNonVirtualCPP
specify this as a non-virtual c++-function

o  beObjectiveC
specify this as an objective-c message send

o  beUnlimitedStack
let this execute on the c-stack (as opposed to the thread-stack)
for unlimited auto-sized-stack under unix/linux.
Ignored under windows.

o  beVirtualCPP
specify this as a virtual c++-function

o  callTypeNumber

o  isAsync
is this executed in a separate thread, in par with the other execution thread(s) ?

o  isCPPFunction
is this a virtual or non-virtual c++-function ?

o  isCallTypeAPI
is this a windows API-call linkage call.
Attention: this uses a different call API (callee unwinds the stack),
and MUST be declared as such for many Kernel functions.
The calltype API is one of the worst historic garbage kept by MS...

o  isCallTypeC
is this a regular C-call (attention: on windows, there are two kinds of calls)

o  isCallTypeOLE
is this an OLE-object call ? (eg. a virtual c++ call; same as isCallTypeCPP)

o  isConstReturnValue
is the pointer return value not to be finalized
(i.e. points to static data or data which is freed by c)

o  isNonVirtualCPP
is this a non-virtual c++-function ?

o  isObjectiveC
is this an objective-C message?

o  isUnlimitedStack
will this execute on the c-stack (as opposed to the thread-stack)
for unlimited auto-sized-stack under unix/linux.
Ignored under windows.

o  isVirtualCPP
is this a virtual c++-function (same as isCallTypeOLE) ?

o  moduleName

o  mustFreeReturnValue
answer true, if a pointer to some C-datum is returned, which must be freed by ST/X.
(i.e. points to malloc'd data which is NOT freed by c)

o  returnType

o  vtableIndex

inspecting
o  inspectorExtraAttributes
( an extension from the stx:libtool package )
extra (pseudo instvar) entries to be shown in an inspector.

invoking
o  invoke

o  invokeCPPVirtualOn: anInstance

o  invokeCPPVirtualOn: instance with: arg

o  invokeCPPVirtualOn: instance with: arg1 with: arg2

o  invokeCPPVirtualOn: instance with: arg1 with: arg2 with: arg3

o  invokeCPPVirtualOn: instance with: arg1 with: arg2 with: arg3 with: arg4

o  invokeCPPVirtualOn: instance withArguments: args

o  invokeWith: arg

o  invokeWith: arg1 with: arg2

o  invokeWith: arg1 with: arg2 with: arg3

o  invokeWith: arg1 with: arg2 with: arg3 with: arg4

o  invokeWithArguments: argArray

printing
o  printOn: aStream
(comment from inherited method)
append a printed representation of the receiver to aStream

private
o  adjustTypes
map all those existing type names to a small number of definite ffi type names.
This is needed, because there are so many different C-type names found in code imported
from various Smalltalk dialects' library function call declarations.
For example: all of word, WORD, unsignedShort, ushort, uShort etc. will map to uint16.
Also, this deals with pointer size differences.

o  convertArgument: arg
a chance to convert arguments to one of the primitive (native) types.

o  linkToModule
link this function to the external module.
I.e. retrieve the module handle and the code pointer.

o  loadLibrary: dllName
load a dll.
Returns a handle or nil.
Notice the dllMapping mechanism, which can be used to silently load different dlls.
This is useful, if some code has a hardcoded dll-name in it, which needs to be changed,
but you do not want or cannot recompile the methods (i.e. no source avail)

o  prepareInvoke
called before invoked.
When called the very first time, moduleHandle is nil,
and we ensure that the dll is loaded, the function address is extracted

private-accessing
o  name: functionNameOrVirtualIndex module: aModuleName returnType: aReturnType argumentTypes: argTypes

o  owningClass

o  owningClass: aClass

o  setModuleName: aModuleName

private-invoking
o  invokeCPPVirtualFFIOn: instance withArguments: arguments

o  invokeFFIWithArguments: arguments

o  invokeFFIwithArguments: argumentsOrNilIn forCPPInstance: aReceiverOrNil
basic invoke mechanism. Calls the function represented by the receiver with argumentsOrNil.
For cplusplus, aReceiverOrNil is required to be an externalStructure like object;
for objectiveC, it must be an ObjectiveC object

o  tryAgainWithAsyncSafeArguments: argumentsOrNil forCPPInstance: aReceiverOrNil
invoked by the call primitive, iff GC-unsave arguments where passed to the call.
Here, allocate non-movable blocks of memory and copy the arguments into them,
then try the call again, copy changed values back, and release the memeory.

testing
o  isExternalLibraryFunction
return true, if the receiver is some kind of externalLibrary function;
true is returned here



ST/X 7.1.0.0; WebServer 1.663 at exept.de:8081; Wed, 19 Sep 2018 12:24:16 GMT