DynamicLoading¶
Usage
use DynamicLoading;
or
import DynamicLoading;
Warning
Dynamic loading support is experimental and unstable.
Support for dynamic loading in Chapel.
Note
To use
this module, the experimental procedure pointer feature
must be activated. Do this by setting the config param
named
useProcedurePointers
to true
.
This module provides the ability to load a binary at runtime. Procedures contained in a dynamically loaded binary can be retrieved and called on any locale without compile-time knowledge of their names or locations.
A hypothetical C binary could contain a procedure named foo
:
// Compile with: 'cc -shared -fPIC -o TestBinary TestBinary.c'
//
// Your C compiler must support compiling a shared library as well
// as generating "position independent code". If your compiler
// offers some other way of preserving symbol tables (e.g., the
// '-rdynamic' flag) for use with dynamic loading, you can compile
// a regular executable with that flag as well.
//
#include <stdio.h>
void foo(void);
void foo(void) {
printf("Hello world from %s!\n", __FUNCTION__);
}
int main(void) {
foo();
return 0;
}
This binary can be can be loaded in Chapel at runtime as follows:
// Compile with: 'chpl Test.chpl -suseProcedurePointers=true'
//
use DynamicLoading;
// A binary may or may not exist at this path.
const path = './TestBinary';
// If loading fails an error will be issued and the 'try!' will halt.
const bin = try! binary.load(path);
And a procedure named foo
with type proc(): void
can be retrieved:
When a procedure is retrieved from a loaded binary, the returned procedure
value is callable on any locale despite binary.retrieve()
only
being called on a single locale. The returned procedure is considered to
be extern
and this is reflected in its type.
Note
Currently, only procedures can be retrieved from loaded binaries. Support for retrieving references to data stored in a binary could be added in the future.
- record binary¶
A wrapper around a dynamically loaded binary.
- proc init=(rhs: binary)¶
The initialized binary refers to the same binary stored in
rhs
.
- proc deinit()¶
- operator =(ref lhs: binary, rhs: binary)¶
After assignment,
lhs
will refer to the same binary stored inrhs
.
- proc type load(path: string) throws¶
Create a record representing a dynamically loaded binary using a string that stores the path to a binary file. The file may be any executable binary, though a “shared library” or “dynamic library” is by far the most common and well supported.
The implementation will attempt to load a binary on all locales. If loading should fail on any locale then the entire process will be aborted and an error will be thrown.
Dynamic loading can fail for a variety of reasons. It can fail if the binary could not be loaded on any locale. It can fail if no file was found at
path
or if a file was found but it did not have a suitable representation (e.g., the file format was not natively executable, or it was not marked as executable).- Arguments:
path : string – The path to the binary file to dynamically load
- Throws:
DynLoadError – if dynamic loading fails
- proc retrieve(name: string, type t) throws where isProcedureType(t)¶
Fetch a procedure from a dynamically loaded binary. Throws an error if no procedure could be found.
Warning
The procedure type
t
provided when callingbinary.retrieve()
is used verbatim and is not checked against the type of the underlying symbol in any way. If the type provided does not match the actual type of the underlying procedure, then the resulting behavior when the retrieved procedure is called is undefined. Crashes or other bugs could occur.The retrieved procedure is considered to be
extern
and will use an extern calling convention, the same as is used for otherextern
procedures declared in Chapel code. This impacts how it can be used. For example, it cannot currently be assigned to a procedure value that is not also consideredextern
.- Arguments:
name : string – The name of the procedure to retrieve
t – The type of the retrieved procedure
- Throws:
DynLoadError – if procedure lookup fails