Clean up to disable target languages that have been neglected/not functional. Target language be fully deleted in SWIG 4.1 unless a new maintainer brings it up to an acceptable status (experimental or supported). Issue #1447
169 lines
7.8 KiB
Text
169 lines
7.8 KiB
Text
This file describes the necessary functions and interfaces a language module
|
|
needs to implement to take advantage of the run time type system. I assume you
|
|
have read the run-time section of the Typemaps chapter in the SWIG
|
|
documentation.
|
|
|
|
Last updated: February 23, 2005
|
|
|
|
The file we are concerned with here should be named langrun.swg. A good example
|
|
of a simple file is the Lib/mzscheme/mzrun.swg file. First, a few requirements
|
|
and notes:
|
|
|
|
1) Every function in this file should be declared static.
|
|
|
|
2) It should be inserted into the runtime section of the _wrap file from your
|
|
config file. The Lib/swigrun.swg file should be included before this file.
|
|
That is, you need to have
|
|
%runtime "swigrun.swg"
|
|
%runtime "langrun.swg"
|
|
|
|
3) You must also include the swiginit.swg file in the init section of the
|
|
wrapper. That is, you should have
|
|
%insert(init) "swiginit.swg"
|
|
|
|
4) From module.cxx, you need to call the SwigType_emit_type_table function, as
|
|
well as register types with SwigType_remember or SwigType_remember_clientdata
|
|
|
|
5) By convention, all functions in this file are of the form
|
|
SWIG_Language_Whatever, and #defines are used to rename SWIG API functions to
|
|
these function names
|
|
|
|
6) You need to call void SWIG_InitializeModule(void *clientdata) from your init
|
|
function.
|
|
|
|
7) You need to implement the runtimeCode() and defaultExternalRuntimeFilename()
|
|
functions inside module.cxx. runtimeCode should return all the language
|
|
specific runtime code as a string, and defaultExternalRuntimeFilename should
|
|
return a string for the default name of the external runtime header. This is
|
|
usually "swigpyrun.h", where "py" is replaced by the language name. These
|
|
two functions are used by the -external-runtime argument.
|
|
|
|
-------------------------------------------------------------------------------
|
|
Required Functions
|
|
-------------------------------------------------------------------------------
|
|
swig_module_info *SWIG_GetModule(void *clientdata);
|
|
void SWIG_SetModule(void *clientdata, swig_module_info *mod);
|
|
|
|
The SetModule function should store the mod argument into some globally
|
|
accessible variable in the target language. The action of these two functions
|
|
is to provide a way for multiple modules to share information. The SetModule
|
|
function should create a new global var named something like
|
|
"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME
|
|
SWIG_RUNTIME_VERSION is currently defined as "2", and SWIG_TYPE_TABLE_NAME is
|
|
defined by the -DSWIG_TYPE_TABLE=mytable option when compiling the wrapper.
|
|
|
|
Alternatively, if the language supports modules, a module named
|
|
"swig_runtime_data" SWIG_RUNTIME_VERSION can be created, and a global variable
|
|
named "type_table" SWIG_TYPE_TABLE_NAME can be created inside it. The most
|
|
common approach is to store the mod pointer in some global variable in the
|
|
target language, but if the language provides an alternative place to store data
|
|
then that is good too.
|
|
|
|
The way the code is set up, SetModule should only be called when GetModule
|
|
returns NULL, and if SetModule is called a second time, the behavior is
|
|
undefined. Just make sure it doesn't crash in the random chance occurrence that
|
|
SetModule is called twice.
|
|
|
|
There are two options here.
|
|
|
|
1) The preferred approach is for GetModule and SetModule to not require a
|
|
clientdata pointer. If you can at all avoid it, please do so. Here, you would
|
|
write swig_module_info *SWIG_Language_GetModule();
|
|
void SWIG_Language_SetModule(swig_module_info *mod);
|
|
and then add
|
|
#define SWIG_GetModule(clientdata) SWIG_Language_GetModule()
|
|
#define SWIG_SetModule(cd, ptr) SWIG_Language_SetModule(ptr)
|
|
You would then call
|
|
SWIG_InitializeModule(0)
|
|
|
|
2) If GetModule and SetModule need to take a custom pointer (most notably an
|
|
environment pointer, see tcl or mzscheme), then you should write
|
|
swig_module_info *SWIG_Language_GetModule(void *clientdata)
|
|
void SWIG_Language_SetModule(void *clientdata, swig_module_info *mod);
|
|
and also define
|
|
#define SWIG_GetModule(cd) SWIG_Language_GetModule(cd)
|
|
#define SWIG_SetModule(cd, ptr) SWIG_Language_SetModule(cd, ptr)
|
|
#define SWIG_MODULE_CLIENTDATA_TYPE Whatever
|
|
SWIG_MODULE_CLIENTDATA_TYPE should be defined to whatever the type of
|
|
clientdata is.
|
|
|
|
You would then call SWIG_InitializeModule(clientdata), and clientdata would get
|
|
passed to GetModule and SetModule. clientdata will not be stored and will only
|
|
be referenced during the InitializeModule call. After InitializeModule returns,
|
|
clientdata does not need to be valid any more.
|
|
|
|
This method is not preferred, because it makes external access to the type
|
|
system more complicated. See the Modules chapter of the documentation, and read
|
|
the "External access to the run-time" section. Then take a look at
|
|
Lib/runtime.swg. Anybody that calls SWIG_TypeQuery needs to pass along the
|
|
clientdata pointer, and that is the reason for defining
|
|
SWIG_MODULE_CLIENTDATA_TYPE.
|
|
|
|
-------------------------------------------------------------------------------
|
|
Standard Functions
|
|
-------------------------------------------------------------------------------
|
|
These functions are not required and their API is not formalized, but almost all
|
|
language modules implement them for consistency across languages. Throughout
|
|
this discussion, I will use LangType to represent the underlying language type
|
|
(Scheme_Object * in mzscheme, PyObject * in python, etc)
|
|
|
|
|
|
|
|
LangObj SWIG_NewPointerObj(void *ptr, swig_type_info *type, int flags);
|
|
Create and return a new pointer object that has both ptr and type. For almost
|
|
all language modules, flags is used for ownership. If flags==1, then the
|
|
created pointer should be registered to be garbage collected.
|
|
|
|
|
|
|
|
int SWIG_ConvertPtr(LangType obj, void **result, swig_type_info *type, int flags);
|
|
Convert a language wrapped pointer into a void *. The pointer is returned in
|
|
result, and the function should return 0 on success, non-zero on error.
|
|
A sample ConvertPtr is given here:
|
|
|
|
swig_cast_info *cast;
|
|
|
|
if (<obj is a wrapped pointer type>) {
|
|
cast = SWIG_TypeCheck(<obj type name>, type);
|
|
cast = SWIG_TypeCheckStruct(<obj type structure>, type);
|
|
if (cast) {
|
|
*result = SWIG_TypeCast(cast, <obj pointer>);
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
|
|
Either TypeCheck or TypeCheckStruct can be called, depending on how the pointer
|
|
is wrapped in langtype. If obj stores the void pointer and the type name, then
|
|
the TypeCheck function should be used, while if obj stores the void pointer and
|
|
a pointer to the swig_type_info structure, then the TypeCheckStruct function
|
|
should be called. The TypeCheckStruct is slightly faster, since it does a
|
|
pointer comparison instead of a strcmp.
|
|
|
|
The flag argument to ConvertPtr is used in some languages for disowning a
|
|
pointer. If the wrapped C function is taking ownership of the pointer (that
|
|
means, the wrapped C function is responsible for deleting the object), then that
|
|
pointer should be removed from the garbage collector. We do that in the
|
|
ConvertPtr function. The pointer is still valid in the target language, but
|
|
when the target language type is garbage collected, it will not call the
|
|
associated destructor. Languages have a special typemap called DISOWN that can be
|
|
applied which passes this argument. All the languages have the flags argument
|
|
for consistency, and the flags argument can be ignored or used for some other
|
|
purpose.
|
|
|
|
|
|
void *SWIG_MustGetPtr(LangType obj, swig_type_info *type, int flags,
|
|
int argnum, const char *func_name) {
|
|
void *result;
|
|
if (SWIG_ConvertPtr(s, &result, type, flags)) {
|
|
generate runtime type error ("Error in func_name, expected a" +
|
|
type->str ? type->str : "void *" +
|
|
"at argument number" + argnum);
|
|
}
|
|
return result;
|
|
}
|
|
This function is optional, and the number and type of parameters can be
|
|
different, but is useful for typemap purposes:
|
|
%typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] {
|
|
$1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, 0, $argnum, FUNC_NAME);
|
|
}
|