diff --git a/SWIG/CHANGES.current b/SWIG/CHANGES.current index 3f5eb0574..18f00543f 100644 --- a/SWIG/CHANGES.current +++ b/SWIG/CHANGES.current @@ -1,5 +1,12 @@ Version 1.3.18 (In progress) ============================ +03/06/2003: mrose (Mark Rose) + The short-lived "-fdirectors" command line option has been + removed. To enable directors, instead use the extended %module + directive as follows: + + %module(directors="1") modulename + 03/06/2003: cheetah (William Fulton) The long long typemaps have been rewritten so that they can be more easily used with non ISO compilers, like Visual C++. For example @@ -44,12 +51,12 @@ Version 1.3.18 (In progress) 03/06/2003: mrose (Mark Rose) Merged the cross-language polymorphism patch. When enabled, C++ - "proxy" classes (called directors) for each specified C++ class. - Directors pass method calls from C++ to Python, similar to the way - the usual proxy (shadow) classes pass method calls from Python to - C++. Together, these two types of proxies allow C++ classes that - are extended in Python to behave just like ordinary C++ classes and - be used in C++ like native objects. + "proxy" classes (called directors) are generated for each specified + C++ class. Directors pass method calls from C++ to Python, similar + to the way the usual proxy (shadow) classes pass method calls from + Python to C++. Together, these two types of proxies allow C++ + classes that are extended in Python to behave just like ordinary + C++ classes and be used in C++ like native objects. This feature is still very experimental and is disabled by default. To enable director support, specify '-fdirectors' on the SWIG command diff --git a/SWIG/Doc/Manual/Python.html b/SWIG/Doc/Manual/Python.html index c4c6f1a1b..a6bbaf961 100644 --- a/SWIG/Doc/Manual/Python.html +++ b/SWIG/Doc/Manual/Python.html @@ -44,38 +44,48 @@
  • Memory management
  • Python 2.2 and classic classes -
  • Common customization features +
  • Cross language polymorphism (experimental) -
  • Tips and techniques +
  • Common customization features -
  • Typemaps +
  • Tips and techniques -
  • Typemap Examples +
  • Typemaps +
  • Typemap Examples + @@ -1899,7 +1909,55 @@ of static member functions. In Python-2.2, they can be accessed via the class itself. In Python-2.1 and earlier, they have to be accessed as a global function or through an instance (see the earlier section). -

    19.5 Common customization features

    +

    19.5 Cross language polymorphism (experimental)

    + +Proxy classes provide a more natural, object-oriented way to access +extension classes. As described above, each proxy instance has an +associated C++ instance, and method calls to the proxy are passed to the +C++ instance transparently via C wrapper functions. + +

    This arrangement is asymmetric in the sense that no corresponding +mechanism exists to pass method calls down the inheritance chain from +C++ to Python. In particular, if a C++ class has been extended in Python +(by extending the proxy class), these extensions will not be visible +from C++ code. Virtual method calls from C++ are thus not able access +the lowest implementation in the inheritance chain. + +

    Change have been made to SWIG 1.3.18 to address this problem and +make the relationship between C++ classes and proxy classes more +symmetric. To achieve this goal, new classes called directors are +introduced at the bottom of the C++ inheritance chain. The job of the +directors is to route method calls correctly, either to C++ +implementations higher in the inheritance chain or to Python +implementations lower in the inheritance chain. The upshot is that C++ +classes can be extended in Python and from C++ these extensions look +exactly like native C++ classes. Neither C++ code nor Python code needs +to know where a particular method is implemented: the combination of +proxy classes, director classes, and c wrapper functions takes care of +all the cross-language method routing transparently. + +

    19.5.1 Command line options

    + + +

    19.5.2 Director classes

    + + +

    19.5.3 Ownership and object destruction

    + + +

    19.5.4 Exception unrolling

    + + +

    19.5.5 Overhead and code bloat

    + + +

    19.5.6 Typemaps

    + + +

    19.5.7 Miscellaneous

    + + +

    19.6 Common customization features

    The last section presented the absolute basics of C/C++ wrapping. If you do nothing @@ -1909,7 +1967,7 @@ types of functionality might be missing or the interface to certain functions mi be awkward. This section describes some common SWIG features that are used to improve your the interface to an extension module. -

    19.5.1 C/C++ helper functions

    +

    19.6.1 C/C++ helper functions

    Sometimes when you create a module, it is missing certain bits of functionality. For @@ -1980,7 +2038,7 @@ Admittedly, this is not the most elegant looking approach. However, it works an hard to implement. It is possible to clean this up using Python code, typemaps, and other customization features as covered in later sections. -

    19.5.2 Adding additional Python code

    +

    19.6.2 Adding additional Python code

    If writing support code in C isn't enough, it is also possible to write code in @@ -2028,7 +2086,7 @@ soon enough. For now, think of this example as an illustration of what can be done without having to rely on any of the more advanced customization features. -

    19.5.3 Class extension with %extend

    +

    19.6.3 Class extension with %extend

    One of the more interesting features of SWIG is that it can extend @@ -2107,7 +2165,7 @@ Vector(12,14,16) %extend works with both C and C++ code. It does not modify the underlying object in any way---the extensions only show up in the Python interface. -

    19.5.4 Exception handling with %exception

    +

    19.6.4 Exception handling with %exception

    If a C or C++ function throws an error, you may want to convert that error into a Python @@ -2220,7 +2278,7 @@ PyExc_ZeroDivisionError The language-independent exception.i library file can also be used to raise exceptions. See the SWIG Library chapter. -

    19.6 Tips and techniques

    +

    19.7 Tips and techniques

    Although SWIG is largely automatic, there are certain types of wrapping problems that @@ -2228,7 +2286,7 @@ require additional user input. Examples include dealing with output parameter strings, binary data, and arrays. This chapter discusses the common techniques for solving these problems. -

    19.6.1 Input and output parameters

    +

    19.7.1 Input and output parameters

    A common problem in some C programs is handling parameters passed as simple pointers. For @@ -2408,7 +2466,7 @@ void foo(Bar *OUTPUT); may not have the intended effect since typemaps.i does not define an OUTPUT rule for Bar. -

    19.6.2 Simple pointers

    +

    19.7.2 Simple pointers

    If you must work with simple pointers such as int * or double * and you don't want to use @@ -2464,7 +2522,7 @@ If you replace %pointer_functions() by %pointer_class(type,name)SWIG Library chapter for further details. -

    19.6.3 Unbounded C Arrays

    +

    19.7.3 Unbounded C Arrays

    Sometimes a C function expects an array to be passed as a pointer. For example, @@ -2518,7 +2576,7 @@ On the other hand, this low-level approach is extremely efficient and well suited for applications in which you need to create buffers, package binary data, etc. -

    19.6.4 String handling

    +

    19.7.4 String handling

    If a C function has an argument of char *, then a Python string @@ -2572,16 +2630,16 @@ If you need to return binary data, you might use the cstring.i library file. The cdata.i library can also be used to extra binary data from arbitrary pointers. -

    19.6.5 Arrays

    +

    19.7.5 Arrays

    -

    19.6.6 String arrays

    +

    19.7.6 String arrays

    -

    19.6.7 STL wrappers

    +

    19.7.7 STL wrappers

    -

    19.7 Typemaps

    +

    19.8 Typemaps

    This section describes how you can modify SWIG's default wrapping behavior @@ -2595,7 +2653,7 @@ part of using SWIG---the default wrapping behavior is enough in most cases. Typemaps are only used if you want to change some aspect of the primitive C-Python interface or if you want to elevate your guru status. -

    19.7.1 What is a typemap?

    +

    19.8.1 What is a typemap?

    A typemap is nothing more than a code generation rule that is attached to @@ -2693,7 +2751,7 @@ parameter is omitted): -

    19.7.2 Python typemaps

    +

    19.8.2 Python typemaps

    The previous section illustrated an "in" typemap for converting Python objects to C. @@ -2725,7 +2783,7 @@ $ cat python.swg Additional typemap examples can also be found in the typemaps.i file. -

    19.7.3 Typemap variables

    +

    19.8.3 Typemap variables

    Within typemap code, a number of special variables prefaced with a $ may appear. @@ -2779,7 +2837,7 @@ properly assigned. The Python name of the wrapper function being created. -

    19.7.4 Useful Python Functions

    +

    19.8.4 Useful Python Functions

    When you write a typemap, you usually have to work directly with Python objects. @@ -2876,14 +2934,14 @@ write me -

    19.8 Typemap Examples

    +

    19.9 Typemap Examples

    This section includes a few examples of typemaps. For more examples, you might look at the files "python.swg" and "typemaps.i" in the SWIG library. -

    19.8.1 Converting Python list to a char **

    +

    19.9.1 Converting Python list to a char **

    A common problem in many C programs is the processing of command line @@ -2956,7 +3014,7 @@ memory allocation is used to allocate memory for the array, the "freearg" typemap is used to later release this memory after the execution of the C function. -

    19.8.2 Expanding a Python object into multiple arguments

    +

    19.9.2 Expanding a Python object into multiple arguments

    Suppose that you had a collection of C functions with arguments @@ -3026,7 +3084,7 @@ to supply the argument count. This is automatically set by the typemap code. F -

    19.8.3 Using typemaps to return arguments

    +

    19.9.3 Using typemaps to return arguments

    A common problem in some C programs is that values may be returned in @@ -3104,7 +3162,7 @@ function can now be used as follows: >>> -

    19.8.4 Mapping Python tuples into small arrays

    +

    19.9.4 Mapping Python tuples into small arrays

    In some applications, it is sometimes desirable to pass small arrays @@ -3145,7 +3203,7 @@ Since our mapping copies the contents of a Python tuple into a C array, such an approach would not be recommended for huge arrays, but for small structures, this approach works fine.

    -

    19.8.5 Mapping sequences to C arrays

    +

    19.9.5 Mapping sequences to C arrays

    Suppose that you wanted to generalize the previous example to handle C @@ -3224,7 +3282,7 @@ static int convert_darray(PyObject *input, double *ptr, int size) { -

    19.8.6 Pointer handling

    +

    19.9.6 Pointer handling

    Occasionally, it might be necessary to convert pointer values that have @@ -3308,4 +3366,4 @@ class object (if applicable).
    SWIG 1.3 - Last Modified : August 7, 2002
    - \ No newline at end of file + diff --git a/SWIG/Lib/python/director.swg b/SWIG/Lib/python/director.swg index 70097f17f..5cca9dd5c 100644 --- a/SWIG/Lib/python/director.swg +++ b/SWIG/Lib/python/director.swg @@ -7,8 +7,6 @@ * Author : Mark Rose (mrose@stm.lbl.gov) ************************************************************************/ -%insert(runtime) %{ - #ifdef __cplusplus #include @@ -179,5 +177,4 @@ int __DIRECTOR__::_up = 0; #endif /* __cplusplus */ -%} diff --git a/SWIG/Source/Modules/lang.cxx b/SWIG/Source/Modules/lang.cxx index cf8666e21..de78f27f5 100644 --- a/SWIG/Source/Modules/lang.cxx +++ b/SWIG/Source/Modules/lang.cxx @@ -1599,12 +1599,6 @@ int Language::classDeclaration(Node *n) { } Setattr(n,"classtype", SwigType_namestr(ClassType)); -/* - if (CPlusPlus) { - classDirector(n); - } -*/ - InClass = 1; CurrentClass = n; @@ -1616,7 +1610,7 @@ int Language::classDeclaration(Node *n) { /* Call classHandler() here */ if (!ImportMode) { - if (CPlusPlus && directorsEnabled()) { + if (directorsEnabled()) { classDirector(n); } classHandler(n); @@ -2105,7 +2099,7 @@ void Language::allow_directors(int val) { * ----------------------------------------------------------------------------- */ int Language::directorsEnabled() const { - return directors; + return directors && CPlusPlus; } /* ----------------------------------------------------------------------------- diff --git a/SWIG/Source/Modules/main.cxx b/SWIG/Source/Modules/main.cxx index c36810952..58e8b8146 100644 --- a/SWIG/Source/Modules/main.cxx +++ b/SWIG/Source/Modules/main.cxx @@ -72,7 +72,6 @@ static char *usage = (char*)"\ -swiglib - Report location of SWIG library and exit\n\ -v - Run in verbose mode\n\ -fcompact - Compile in compact mode\n\ - -fdirectors - Enable C++ directors\n\ -fvirtual - Compile in virtual elimination mode\n\ -small - Compile in virtual elimination & compact mode\n\ -version - Print SWIG version number\n\ @@ -190,7 +189,6 @@ int SWIG_main(int argc, char *argv[], Language *l) { int dump_classes = 0; int werror = 0; int depend = 0; - int directors = 0; DOH *libfiles = 0; DOH *cpps = 0 ; @@ -287,9 +285,6 @@ int SWIG_main(int argc, char *argv[], Language *l) { } else if (strcmp(temp, "-small") == 0) { Wrapper_compact_print_mode_set(1); Wrapper_virtual_elimination_mode_set(1); - } else if (strcmp(temp, "-fdirectors") == 0) { - directors = 1; - lang->allow_directors(); } } } @@ -329,10 +324,6 @@ int SWIG_main(int argc, char *argv[], Language *l) { Wrapper_compact_print_mode_set(1); Wrapper_virtual_elimination_mode_set(1); Swig_mark_arg(i); - } else if (strcmp(argv[i], "-fdirectors") == 0) { - directors = 1; - lang->allow_directors(); - Swig_mark_arg(i); } else if (strcmp(argv[i],"-c") == 0) { NoInclude=1; Preprocessor_define((DOH *) "SWIG_NOINCLUDE 1", 0); @@ -543,9 +534,6 @@ int SWIG_main(int argc, char *argv[], Language *l) { if (lang_config) { Printf(fs,"\n%%include \"%s\"\n", lang_config); } - if (directors) { - Printf(fs,"\n%%include \"director.swg\"\n"); - } Printf(fs,"%%include \"%s\"\n", Swig_last_file()); for (i = 0; i < Len(libfiles); i++) { Printf(fs,"\n%%include \"%s\"\n", Getitem(libfiles,i)); diff --git a/SWIG/Source/Modules/python.cxx b/SWIG/Source/Modules/python.cxx index 66a78c5cb..f79ba8183 100644 --- a/SWIG/Source/Modules/python.cxx +++ b/SWIG/Source/Modules/python.cxx @@ -376,6 +376,26 @@ public: virtual int top(Node *n) { + /* check if directors are enabled for this module. note: this + * is a "master" switch, without which no director code will be + * emitted. %feature("director") statements are also required + * to enable directors for individual classes or methods. + * + * use %module(directors="1") modulename at the start of the + * interface file to enable director generation. + */ + { + Node *module = Getattr(n, "module"); + if (module) { + Node *options = Getattr(module, "options"); + if (options) { + if (Getattr(options, "directors")) { + allow_directors(); + } + } + } + } + /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); String *outfile_h = Getattr(n, "outfile_h"); @@ -386,7 +406,7 @@ public: SWIG_exit(EXIT_FAILURE); } - if (CPlusPlus && directorsEnabled()) { + if (directorsEnabled()) { f_runtime_h = NewFile(outfile_h,"w"); if (!f_runtime_h) { Printf(stderr,"*** Can't open '%s'\n", outfile_h); @@ -422,11 +442,12 @@ public: module = Copy(Getattr(n,"name")); mainmodule = Getattr(n,"name"); - if (CPlusPlus) { + if (directorsEnabled()) { Swig_banner(f_directors_h); Printf(f_directors_h, "#ifndef __%s_WRAP_H__\n", module); Printf(f_directors_h, "#define __%s_WRAP_H__\n\n", module); Printf(f_directors_h, "class __DIRECTOR__;\n\n"); + Swig_insert_file("director.swg", f_directors); Printf(f_directors, "\n\n"); Printf(f_directors, "/* ---------------------------------------------------\n"); Printf(f_directors, " * C++ director class methods\n"); @@ -548,7 +569,7 @@ public: /* Close all of the files */ Dump(f_header,f_runtime); - if (CPlusPlus && directorsEnabled()) { + if (directorsEnabled()) { Dump(f_directors, f_runtime); Dump(f_directors_h, f_runtime_h); Printf(f_runtime_h, "\n"); @@ -844,7 +865,7 @@ public: // (the smart-pointer) and the director object (the "pointee") are // distinct. - if (CPlusPlus && directorsEnabled()) { + if (directorsEnabled()) { if (!is_smart_pointer()) { if (/*directorbase &&*/ hasVirtual && !constructor && isVirtual) { Wrapper_add_local(f, "director", "__DIRECTOR__ *director = 0");