|
Class: ExternalLibraryFunction
Object
|
+--ExecutableFunction
|
+--ExternalFunction
|
+--ExternalLibraryFunction
- Package:
- stx:libbasic
- Category:
- System-Support
- Version:
- rev:
1.193
date: 2019/07/22 05:25:53
- user: cg
- 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
constants
-
callTypeAPI
-
-
callTypeC
-
-
callTypeCDecl
-
-
callTypeMASK
-
-
callTypeOLE
-
-
callTypeUNIX64
-
-
invokeSelectors
-
debugging
-
verbose: aBoolean
-
turn on/off tracing of calls
usage example(s):
ExternalLibraryFunction verbose:true
|
instance creation
-
name: functionName module: moduleName callType: callTypeSymbol returnType: returnType argumentTypes: argTypes
-
-
name: functionName module: moduleName returnType: returnType argumentTypes: argTypes
-
type name mapping
-
adjustAllTypes
-
because adjustTypes is invoked only once (when the ext-call is first created),
any change in the type mapping (ffiTypeSymbolForType: or mapType) will not
affect existing lib-calls.
Use this, to adjust all thoseafter a change in the type 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
-
mapType: aTypeSymbol toFFI: mappedType
-
additional user defined type map:
eg. self mapType:#INT8 toFFI:#int8
allows use of INT8 in external function api declarations.
mappedType should be 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
-
callType: aSymbol
-
-
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
-
call the function with no arguments
-
invokeCPPVirtualOn: anInstance
-
call a CPP virtual function with no arguments
-
invokeCPPVirtualOn: anInstance with: arg
-
call a CPP virtual function with 1 argument
-
invokeCPPVirtualOn: anInstance with: arg1 with: arg2
-
call a CPP virtual function with 2 arguments
-
invokeCPPVirtualOn: anInstance with: arg1 with: arg2 with: arg3
-
call a CPP virtual function with 3 arguments
-
invokeCPPVirtualOn: anInstance with: arg1 with: arg2 with: arg3 with: arg4
-
call a CPP virtual function with 4 arguments
-
invokeCPPVirtualOn: anInstance withArguments: args
-
call a CPP virtual function with up to maxArgs (15) arguments
-
invokeObjCOn: anInstance
-
call an ObjC method with no arguments
-
invokeObjCOn: anInstance withArguments: args
-
call an ObjC method with up to maxArgs (15) arguments
-
invokeWith: arg
-
call the function with 1 argument
-
invokeWith: arg1 with: arg2
-
call the function with 2 arguments
-
invokeWith: arg1 with: arg2 with: arg3
-
call the function with 3 arguments
-
invokeWith: arg1 with: arg2 with: arg3 with: arg4
-
call the function with 4 arguments
-
invokeWithArguments: argArray
-
call the function with up to maxArgs (15) arguments
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.
The name of the DLL is retrieved either from the primitive declaration or
the owning instance or its class
-
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
-
prepareObjCInvoke
-
called before invoked
private-accessing
-
name: functionNameOrVirtualIndex module: aModuleName returnType: aReturnType argumentTypes: argTypes
-
-
owningClass
-
-
owningClass: aClass
-
-
setModuleName: aModuleName
-
private-invoking
-
invokeCPPVirtualFFIOn: instance withArguments: arguments
-
-
invokeFFIWithArguments: arguments
-
-
invokeFFIwithArguments: argumentsOrNilArg forInstance: 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 forInstance: 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
|