diff --git a/CHANGES.current b/CHANGES.current index baf68ee4e..371b280fc 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,14 @@ Version 1.3.37 (in progress) ============================= +2008-09-18: wsfulton + Document the optional module attribute in the %import directive, + see Modules.html. Add a warning for Python wrappers when the + module name for an imported base class is missing, requiring the + module attribute to be added to %import, eg + + %import(module="FooModule") foo.h + 2008-09-18: olly [PHP5] Change the default input typemap for char * to turn PHP Null into C NULL (previously it was converted to an empty string). diff --git a/Doc/Manual/Modules.html b/Doc/Manual/Modules.html index 8971324fb..9b8fd85e5 100644 --- a/Doc/Manual/Modules.html +++ b/Doc/Manual/Modules.html @@ -50,41 +50,90 @@ scripting language runtime as you would do for the single module case.

A bit more complex is the case in which modules need to share information. -For example, when one module extends the class of the another by deriving from +For example, when one module extends the class of another by deriving from it:

-%module base
-
-%inline %{
+// File: base.h
 class base {
 public:
-       int foo(void);
+  int foo();
 };
-%}
 
  -
-%module derived
 
-%import "base.i"
+
+// File: base_module.i
+%module base_module
+
+%{
+#include "base.h"
+%}
+%include "base.h"
+
+  + +
+// File: derived_module.i
+%module derived_module
+
+%import "base_module.i"
 
 %inline %{
 class derived : public base {
 public:
-       int bar(void);
+  int bar();
 };
 %}
 
-

To create the wrapper properly, module derived needs to know the -base class and that it's interface is covered in another module. The -line %import "base.i" lets SWIG know exactly that. The common mistake here is -to %import the .h file instead of the .i, which sadly won't do the trick. Another issue -to take care of is that multiple dependent wrappers should not be linked/loaded +

To create the wrapper properly, module derived_module needs to know about the +base class and that its interface is covered in another module. The +line %import "base_module.i" lets SWIG know exactly that. Oftentimes +the .h file is passed to %import instead of the .i, +which unfortunately doesn't work for all language modules. For example, Python requires the +name of module that the base class exists in so that the proxy classes can fully inherit the +base class's methods. Typically you will get a warning when the module name is missing, eg: +

+ +
+derived_module.i:8: Warning(401): Base class 'base' ignored - unknown module name for base. Either import 
+the appropriate module interface file or specify the name of the module in the %import directive.
+
+ +

+It is sometimes desirable to import the header file rather than the interface file and overcome +the above warning. +For example in the case of the imported interface being quite large, it may be desirable to +simplify matters and just import a small header file of dependent types. +This can be done by specifying the optional module attribute in the %import directive. +The derived_module.i file shown above could be replaced with the following: + +

+// File: derived_module.i
+%module derived_module
+
+%import(module="base_module") "base.h"
+
+%inline %{
+class derived : public base {
+public:
+  int bar();
+};
+
+ +

+Note that "base_module" is the module name and is the same as that specified in %module +in base_module.i as well as the %import in derived_module.i. +

+ +

+Another issue +to beware of is that multiple dependent wrappers should not be linked/loaded in parallel from multiple threads as SWIG provides no locking - for more on that issue, read on.

+

15.2 The SWIG runtime code

diff --git a/Doc/Manual/Preprocessor.html b/Doc/Manual/Preprocessor.html index a454c8124..d79ad7377 100644 --- a/Doc/Manual/Preprocessor.html +++ b/Doc/Manual/Preprocessor.html @@ -81,7 +81,7 @@ Such information generally includes type declarations (e.g., typedef) a C++ classes that might be used as base-classes for class declarations in the interface. The use of %import is also important when SWIG is used to generate extensions as a collection of related modules. This is an advanced topic and is described -in a later chapter. +in later in the Working with Modules chapter.

diff --git a/Examples/test-suite/import_nomodule.i b/Examples/test-suite/import_nomodule.i index 5d5115360..a1ba9ad7a 100644 --- a/Examples/test-suite/import_nomodule.i +++ b/Examples/test-suite/import_nomodule.i @@ -3,6 +3,9 @@ #include "import_nomodule.h" %} +// For Python +%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Bar; // Base class 'Foo' ignored - unknown module name for base. Either import the appropriate module interface file or specify the name of the module in the %import directive. + %import "import_nomodule.h" #if !defined(SWIGJAVA) && !defined(SWIGRUBY) && !defined(SWIGCSHARP) diff --git a/Examples/test-suite/imports_b.i b/Examples/test-suite/imports_b.i index afc573a39..81e84cddd 100644 --- a/Examples/test-suite/imports_b.i +++ b/Examples/test-suite/imports_b.i @@ -34,9 +34,14 @@ */ #if 0 -%import "imports_a.i" + %import "imports_a.i" #else -%import(module="imports_a") "imports_a.h" +# if 0 + // Test Warning 401 (Python only) + %import "imports_a.h" +# else + %import(module="imports_a") "imports_a.h" +# endif #endif %include "imports_b.h" diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index 7a878b4f8..7298c5f9e 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -2864,7 +2864,12 @@ public: b = First(baselist); while (b.item) { String *bname = Getattr(b.item, "python:proxy"); - if (!bname || GetFlag(b.item, "feature:ignore")) { + bool ignore = GetFlag(b.item, "feature:ignore") ? true : false; + if (!bname || ignore) { + if (!bname && !ignore) { + Swig_warning(WARN_TYPE_UNDEFINED_CLASS, input_file, line_number, + "Base class '%s' ignored - unknown module name for base. Either import the appropriate module interface file or specify the name of the module in the %%import directive.\n", SwigType_namestr(Getattr(b.item, "name"))); + } b = Next(b); continue; }