| 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); |
| } |