- Improve the runtime type sytesm
- Update all languages to new type system - Add DohSortList function - Fix mzscheme Examples/Makefile git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@6930 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
58cd593dae
commit
f6964f285f
48 changed files with 1383 additions and 1021 deletions
152
SWIG/Doc/Devel/runtime.txt
Normal file
152
SWIG/Doc/Devel/runtime.txt
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
This file describes the necissary 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: January 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.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
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
|
||||
accessable 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.
|
||||
|
||||
Alternativly, 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
|
||||
(like the chicken module), 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 occurance that
|
||||
SetModule is called twice.
|
||||
|
||||
There are two options here.
|
||||
|
||||
1) The perferred 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_Langauge_SetModule(void *clientdata, swig_module_info *mod);
|
||||
and also define
|
||||
#define SWIG_GetModule(cd) SWIG_Langauge_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 consistancy across languages. Throughout
|
||||
this discussion, I will use LangType to represent the underlying language type
|
||||
(C_word in chicken, 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.
|
||||
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue