|
Class: ExternalLibraryFunction
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
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 initialization
-
addToDllPath: aDirectoryPathName
-
can be used during initialization, to add more places for dll-loading
usage example(s):
self addToDllPath:'c:\matrix\API\dll'
|
-
defaultDLLPath
-
return a default dll-path, as per operating system
usage example(s):
-
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'
-
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'
-
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'
-
dllPath
-
provide a default dllPath, where external libraries are searched for
usage example(s):
ExternalLibraryFunction dllPath
|
-
dllPath: aCollectionOfDirectoryPathNames
-
provide a default dllPath, where external libraries are searched for
-
flushModuleHandlesForLibrary: aLibraryName
-
self flushModuleHandlesForLibrary:'ole32.dll'
-
flushModuleHandlesForWhich: aBlock
-
self flushModuleHandlesForLibrary:'ole32.dll'
-
initialize
-
using inline access to corresponding c--defines to avoid duplicate places of knowledge
usage example(s):
DLLPATH := nil.
self initialize
|
-
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
-
callTypeAPI
-
-
callTypeC
-
-
callTypeCDecl
-
-
callTypeMASK
-
-
callTypeOLE
-
-
callTypeUNIX64
-
debugging
-
verbose: aBoolean
-
turn on/off tracing of calls
usage example(s):
ExternalLibraryFunction verbose:true
|
instance creation
-
name: functionName module: moduleName returnType: returnType argumentTypes: argTypes
-
type name mapping
-
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
accessing
-
argumentTypes
-
-
argumentTypesString
-
-
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).
-
beCallTypeAPI
-
-
beCallTypeC
-
-
beCallTypeOLE
-
-
beCallTypeUNIX64
-
-
beCallTypeV8
-
-
beCallTypeV9
-
-
beCallTypeWINAPI
-
-
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)
-
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)
-
beNonVirtualCPP
-
specify this as a non-virtual c++-function
-
beObjectiveC
-
specify this as an objective-c message send
-
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.
-
beVirtualCPP
-
specify this as a virtual c++-function
-
callTypeNumber
-
-
isAsync
-
is this executed in a separate thread, in par with the other execution thread(s) ?
-
isCPPFunction
-
is this a virtual or non-virtual c++-function ?
-
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...
-
isCallTypeC
-
is this a regular C-call (attention: on windows, there are two kinds of calls)
-
isCallTypeOLE
-
is this an OLE-object call ? (eg. a virtual c++ call; same as isCallTypeCPP)
-
isConstReturnValue
-
is the pointer return value not to be finalized
(i.e. points to static data or data which is freed by c)
-
isNonVirtualCPP
-
is this a non-virtual c++-function ?
-
isObjectiveC
-
is this an objective-C message?
-
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.
-
isVirtualCPP
-
is this a virtual c++-function (same as isCallTypeOLE) ?
-
moduleName
-
-
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)
-
returnType
-
-
vtableIndex
-
inspecting
-
inspectorExtraAttributes ( an extension from the stx:libtool package )
-
extra (pseudo instvar) entries to be shown in an inspector.
invoking
-
invoke
-
-
invokeCPPVirtualOn: anInstance
-
-
invokeCPPVirtualOn: instance with: arg
-
-
invokeCPPVirtualOn: instance with: arg1 with: arg2
-
-
invokeCPPVirtualOn: instance with: arg1 with: arg2 with: arg3
-
-
invokeCPPVirtualOn: instance with: arg1 with: arg2 with: arg3 with: arg4
-
-
invokeCPPVirtualOn: instance withArguments: args
-
-
invokeWith: arg
-
-
invokeWith: arg1 with: arg2
-
-
invokeWith: arg1 with: arg2 with: arg3
-
-
invokeWith: arg1 with: arg2 with: arg3 with: arg4
-
-
invokeWithArguments: argArray
-
printing
-
printOn: aStream
-
(comment from inherited method)
append a printed representation of the receiver to aStream
private
-
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.
-
convertArgument: arg
-
a chance to convert arguments to one of the primitive (native) types.
-
linkToModule
-
link this function to the external module.
I.e. retrieve the module handle and the code pointer.
-
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)
-
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
-
name: functionNameOrVirtualIndex module: aModuleName returnType: aReturnType argumentTypes: argTypes
-
-
owningClass
-
-
owningClass: aClass
-
-
setModuleName: aModuleName
-
private-invoking
-
invokeCPPVirtualFFIOn: instance withArguments: arguments
-
-
invokeFFIWithArguments: arguments
-
-
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
-
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
-
isExternalLibraryFunction
-
return true, if the receiver is some kind of externalLibrary function;
true is returned here
|