From 747e22f714e793ae619545e284496275e0fb7169 Mon Sep 17 00:00:00 2001 From: Frederick Parotat Date: Wed, 3 Jun 2015 14:19:13 +0200 Subject: [PATCH 1/6] [C#] Single file mode Added "-csout " parameter. If supplied all generated C# code will be written to the given file. Makes it easier to integrate SWIG into automated script based build processes. --- Source/Modules/csharp.cxx | 139 ++++++++++++++++++++------------------ 1 file changed, 73 insertions(+), 66 deletions(-) diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index b251ff892..dda5bb528 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -34,6 +34,7 @@ class CSHARP:public Language { File *f_init; File *f_directors; File *f_directors_h; + File *f_single; List *filenames_list; bool proxy_flag; // Flag for generating proxy classes @@ -78,6 +79,7 @@ class CSHARP:public Language { String *director_method_types; // Director method types String *director_connect_parms; // Director delegates parameter list for director connect call String *destructor_call; //C++ destructor call if any + String *cs_out; // Director method stuff: List *dmethods_seq; @@ -108,6 +110,7 @@ public: f_init(NULL), f_directors(NULL), f_directors_h(NULL), + f_single(NULL), filenames_list(NULL), proxy_flag(true), native_function_flag(false), @@ -150,6 +153,7 @@ public: director_method_types(NULL), director_connect_parms(NULL), destructor_call(NULL), + cs_out(NULL), dmethods_seq(NULL), dmethods_table(NULL), n_dmethods(0), @@ -244,6 +248,16 @@ public: } else if (strcmp(argv[i], "-oldvarnames") == 0) { Swig_mark_arg(i); old_variable_names = true; + } else if (strcmp(argv[i], "-csout") == 0) { + if (argv[i + 1]) { + cs_out = NewString(""); + Printf(cs_out, argv[i + 1]); + Swig_mark_arg(i); + Swig_mark_arg(i + 1); + i++; + } else { + Swig_arg_error(); + } } else if (strcmp(argv[i], "-help") == 0) { Printf(stdout, "%s\n", usage); } @@ -423,18 +437,7 @@ public: } // Generate the intermediary class { - String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), imclass_name); - File *f_im = NewFile(filen, "w", SWIG_output_files()); - if (!f_im) { - FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the intermediary class file - emitBanner(f_im); + File *f_im = getFile(SWIG_output_directory(), imclass_name); addOpenNamespace(0, f_im); @@ -462,23 +465,13 @@ public: Printf(f_im, "}\n"); addCloseNamespace(0, f_im); - Delete(f_im); + if(f_im != f_single) + Delete(f_im); } // Generate the C# module class { - String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), module_class_name); - File *f_module = NewFile(filen, "w", SWIG_output_files()); - if (!f_module) { - FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the module class file - emitBanner(f_module); + File *f_module = getFile(SWIG_output_directory(), module_class_name); addOpenNamespace(0, f_module); @@ -514,7 +507,8 @@ public: Printf(f_module, "}\n"); addCloseNamespace(0, f_module); - Delete(f_module); + if(f_module != f_single) + Delete(f_module); } if (upcasts_code) @@ -613,6 +607,11 @@ public: f_directors_h = NULL; } + if(f_single) { + Dump(f_single, f_begin); + Delete(f_single); + } + Dump(f_wrappers, f_begin); Wrapper_pretty_print(f_init, f_begin); Delete(f_header); @@ -634,6 +633,44 @@ public: Swig_banner_target_lang(f, "//"); Printf(f, "//------------------------------------------------------------------------------\n\n"); } + + /* ----------------------------------------------------------------------------- + * getFile() + * ----------------------------------------------------------------------------- */ + + File* getFile(const String* dir, String* name) { + if(cs_out) { + if(!f_single) { + String* filen = NewStringf("%s", cs_out); + f_single = NewFile(filen, "w", SWIG_output_files()); + if(!f_single) { + FileErrorDisplay(filen); + SWIG_exit(EXIT_FAILURE); + } + Append(filenames_list, Copy(filen)); + Delete(filen); + filen = NULL; + + Printf(stdout, "create single file"); + + emitBanner(f_single); + } + return f_single; + } else { + String* filen = NewStringf("%s%s.cs", dir, name); + File* f = NewFile(filen, "w", SWIG_output_files()); + if(!f) { + FileErrorDisplay(f); + SWIG_exit(EXIT_FAILURE); + } + Append(filenames_list, Copy(filen)); + Delete(filen); + filen = NULL; + + emitBanner(f); + return f; + } + } /*----------------------------------------------------------------------- * Add new director upcall signature @@ -1198,18 +1235,7 @@ public: } else { // Global enums are defined in their own file String *output_directory = outputDirectory(nspace); - String *filen = NewStringf("%s%s.cs", output_directory, symname); - File *f_enum = NewFile(filen, "w", SWIG_output_files()); - if (!f_enum) { - FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the enum file - emitBanner(f_enum); + File *f_enum = getFile(output_directory, symname); addOpenNamespace(nspace, f_enum); @@ -1217,7 +1243,8 @@ public: "\n", enum_code, "\n", NIL); addCloseNamespace(nspace, f_enum); - Delete(f_enum); + if(f_enum != f_single) + Delete(f_enum); Delete(output_directory); } } else { @@ -1920,18 +1947,7 @@ public: // Each outer proxy class goes into a separate file if (!has_outerclass) { String *output_directory = outputDirectory(nspace); - String *filen = NewStringf("%s%s.cs", output_directory, proxy_class_name); - f_proxy = NewFile(filen, "w", SWIG_output_files()); - if (!f_proxy) { - FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the proxy class file - emitBanner(f_proxy); + f_proxy = getFile(output_directory, proxy_class_name); addOpenNamespace(nspace, f_proxy); } @@ -1991,7 +2007,8 @@ public: if (!has_outerclass) { Printf(f_proxy, "}\n"); addCloseNamespace(nspace, f_proxy); - Delete(f_proxy); + if(f_proxy != f_single) + Delete(f_proxy); f_proxy = NULL; } else { for (int i = 0; i < nesting_depth; ++i) @@ -3216,18 +3233,7 @@ public: Setline(n, line_number); String *swigtype = NewString(""); - String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), classname); - File *f_swigtype = NewFile(filen, "w", SWIG_output_files()); - if (!f_swigtype) { - FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; - - // Start writing out the type wrapper class file - emitBanner(f_swigtype); + File *f_swigtype = getFile(SWIG_output_directory(), classname); addOpenNamespace(0, f_swigtype); @@ -3262,8 +3268,8 @@ public: Printv(f_swigtype, swigtype, NIL); addCloseNamespace(0, f_swigtype); - - Delete(f_swigtype); + if(f_swigtype != f_single) + Delete(f_swigtype); Delete(swigtype); Delete(n); } @@ -4285,4 +4291,5 @@ C# Options (available with -csharp)\n\ -noproxy - Generate the low-level functional interface instead\n\ of proxy classes\n\ -oldvarnames - Old intermediary method names for variable wrappers\n\ + -csout - Write all C# to a single file located at \n\ \n"; From 0b0997821926b4e615286a8ad42de805d1f6912d Mon Sep 17 00:00:00 2001 From: Frederick Parotat Date: Wed, 3 Jun 2015 14:26:38 +0200 Subject: [PATCH 2/6] [C#] Single file mode (minor fix) Removed debug output --- Source/Modules/csharp.cxx | 2 -- 1 file changed, 2 deletions(-) diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index dda5bb528..7ebb9ff64 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -651,8 +651,6 @@ public: Delete(filen); filen = NULL; - Printf(stdout, "create single file"); - emitBanner(f_single); } return f_single; From b83307e3547bcd643fc6b76bfdc09d736e308e32 Mon Sep 17 00:00:00 2001 From: Frederick Parotat Date: Thu, 4 Jun 2015 14:15:00 +0200 Subject: [PATCH 3/6] [C#] Single file mode (fixes) Renamed argument '-csout' to '-outfile'. Reformatting (Tab spacing; Pointer style). Chagned html documentation. --- Doc/Manual/CSharp.html | 25 +++++++++ Source/Modules/csharp.cxx | 115 +++++++++++++++++++++----------------- 2 files changed, 89 insertions(+), 51 deletions(-) diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html index ba49fa004..28d6d2b2e 100644 --- a/Doc/Manual/CSharp.html +++ b/Doc/Manual/CSharp.html @@ -13,6 +13,9 @@ +Differences to the Java module
  • Void pointers
  • C# Arrays @@ -79,6 +82,28 @@ Monodoc, available from the Mono project, has a very useful section titled using directives in generated code. This breaks backwards compatibility with typemaps, pragmas, etc written for use with SWIG 2 that assume the presence of using System; or using System.Runtime.InteropServices; directives in the intermediate class imports, module imports, or proxy imports. SWIG 3 supports backwards compatibility though the use of the SWIG2_CSHARP macro. If SWIG2_CSHARP is defined, SWIG 3 generates using directives in the intermediate class, module class, and proxy class code similar to those generated by SWIG 2. This can be done without modifying any of the input code by passing the -DSWIG2_CSHARP commandline parameter when executing swig.

    +

    20.1.2 C# Command Line Options

    + + +

    Additional command line options that can be used to control code generation:

    + +

    +-outfile <filename>
    +This command line will instruct the C# module to write all generated C# code to <filename> (located in the output directory) instead of creating separate files for generated classes.
    +Caveats: +

      + +
    • +The file extension (.cs) will not be automatically be added and needs to be provided. +
    • + +
    • +Due to possible compiler limits it is not advisable to use -outfile when generating wrappers for big projects. +
    • + +
    +

    +

    20.2 Differences to the Java module

    diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index 7ebb9ff64..ad27a5bea 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -34,7 +34,7 @@ class CSHARP:public Language { File *f_init; File *f_directors; File *f_directors_h; - File *f_single; + File *f_single_out; List *filenames_list; bool proxy_flag; // Flag for generating proxy classes @@ -79,7 +79,7 @@ class CSHARP:public Language { String *director_method_types; // Director method types String *director_connect_parms; // Director delegates parameter list for director connect call String *destructor_call; //C++ destructor call if any - String *cs_out; + String *output_file; // File name for single file mode. If set all generated code will be written to this file // Director method stuff: List *dmethods_seq; @@ -110,7 +110,7 @@ public: f_init(NULL), f_directors(NULL), f_directors_h(NULL), - f_single(NULL), + f_single_out(NULL), filenames_list(NULL), proxy_flag(true), native_function_flag(false), @@ -153,7 +153,7 @@ public: director_method_types(NULL), director_connect_parms(NULL), destructor_call(NULL), - cs_out(NULL), + output_file(NULL), dmethods_seq(NULL), dmethods_table(NULL), n_dmethods(0), @@ -248,10 +248,10 @@ public: } else if (strcmp(argv[i], "-oldvarnames") == 0) { Swig_mark_arg(i); old_variable_names = true; - } else if (strcmp(argv[i], "-csout") == 0) { + } else if (strcmp(argv[i], "-outfile") == 0) { if (argv[i + 1]) { - cs_out = NewString(""); - Printf(cs_out, argv[i + 1]); + output_file = NewString(""); + Printf(output_file, argv[i + 1]); Swig_mark_arg(i); Swig_mark_arg(i + 1); i++; @@ -437,7 +437,7 @@ public: } // Generate the intermediary class { - File *f_im = getFile(SWIG_output_directory(), imclass_name); + File *f_im = getOutputFile(SWIG_output_directory(), imclass_name); addOpenNamespace(0, f_im); @@ -465,13 +465,14 @@ public: Printf(f_im, "}\n"); addCloseNamespace(0, f_im); - if(f_im != f_single) - Delete(f_im); + if(f_im != f_single_out) + Delete(f_im); + f_im = NULL; } // Generate the C# module class { - File *f_module = getFile(SWIG_output_directory(), module_class_name); + File *f_module = getOutputFile(SWIG_output_directory(), module_class_name); addOpenNamespace(0, f_module); @@ -507,8 +508,9 @@ public: Printf(f_module, "}\n"); addCloseNamespace(0, f_module); - if(f_module != f_single) - Delete(f_module); + if(f_module != f_single_out) + Delete(f_module); + f_module = NULL; } if (upcasts_code) @@ -607,9 +609,10 @@ public: f_directors_h = NULL; } - if(f_single) { - Dump(f_single, f_begin); - Delete(f_single); + if(f_single_out) { + Dump(f_single_out, f_begin); + Delete(f_single_out); + f_single_out = NULL; } Dump(f_wrappers, f_begin); @@ -635,32 +638,40 @@ public: } /* ----------------------------------------------------------------------------- - * getFile() + * getOutputFile() + * + * Prepares a File object by creating the file in the file system and + * writing the banner for auto-generated files to it (emitBanner). + * If '-outfile' is provided (single file mode) the supplied parameters will + * be ignored and the returned file will always be: + * / + * Otherwise the file will be: + * /.cs * ----------------------------------------------------------------------------- */ - File* getFile(const String* dir, String* name) { - if(cs_out) { - if(!f_single) { - String* filen = NewStringf("%s", cs_out); - f_single = NewFile(filen, "w", SWIG_output_files()); - if(!f_single) { - FileErrorDisplay(filen); - SWIG_exit(EXIT_FAILURE); - } - Append(filenames_list, Copy(filen)); - Delete(filen); - filen = NULL; + File *getOutputFile(const String* dir, String* name) { + if(output_file) { + if(!f_single_out) { + String *filen = NewStringf("%s%s", SWIG_output_directory(), output_file); + f_single_out = NewFile(filen, "w", SWIG_output_files()); + if(!f_single_out) { + FileErrorDisplay(filen); + SWIG_exit(EXIT_FAILURE); + } + Append(filenames_list, Copy(filen)); + Delete(filen); + filen = NULL; - emitBanner(f_single); - } - return f_single; + emitBanner(f_single_out); + } + return f_single_out; } else { - String* filen = NewStringf("%s%s.cs", dir, name); - File* f = NewFile(filen, "w", SWIG_output_files()); + String *filen = NewStringf("%s%s.cs", dir, name); + File *f = NewFile(filen, "w", SWIG_output_files()); if(!f) { - FileErrorDisplay(f); - SWIG_exit(EXIT_FAILURE); - } + FileErrorDisplay(f); + SWIG_exit(EXIT_FAILURE); + } Append(filenames_list, Copy(filen)); Delete(filen); filen = NULL; @@ -1233,7 +1244,7 @@ public: } else { // Global enums are defined in their own file String *output_directory = outputDirectory(nspace); - File *f_enum = getFile(output_directory, symname); + File *f_enum = getOutputFile(output_directory, symname); addOpenNamespace(nspace, f_enum); @@ -1241,8 +1252,9 @@ public: "\n", enum_code, "\n", NIL); addCloseNamespace(nspace, f_enum); - if(f_enum != f_single) - Delete(f_enum); + if(f_enum != f_single_out) + Delete(f_enum); + f_enum = NULL; Delete(output_directory); } } else { @@ -1945,7 +1957,7 @@ public: // Each outer proxy class goes into a separate file if (!has_outerclass) { String *output_directory = outputDirectory(nspace); - f_proxy = getFile(output_directory, proxy_class_name); + f_proxy = getOutputFile(output_directory, proxy_class_name); addOpenNamespace(nspace, f_proxy); } @@ -2005,8 +2017,8 @@ public: if (!has_outerclass) { Printf(f_proxy, "}\n"); addCloseNamespace(nspace, f_proxy); - if(f_proxy != f_single) - Delete(f_proxy); + if(f_proxy != f_single_out) + Delete(f_proxy); f_proxy = NULL; } else { for (int i = 0; i < nesting_depth; ++i) @@ -3231,7 +3243,7 @@ public: Setline(n, line_number); String *swigtype = NewString(""); - File *f_swigtype = getFile(SWIG_output_directory(), classname); + File *f_swigtype = getOutputFile(SWIG_output_directory(), classname); addOpenNamespace(0, f_swigtype); @@ -3266,8 +3278,9 @@ public: Printv(f_swigtype, swigtype, NIL); addCloseNamespace(0, f_swigtype); - if(f_swigtype != f_single) + if(f_swigtype != f_single_out) Delete(f_swigtype); + f_swigtype = NULL; Delete(swigtype); Delete(n); } @@ -4284,10 +4297,10 @@ extern "C" Language *swig_csharp(void) { const char *CSHARP::usage = "\ C# Options (available with -csharp)\n\ - -dllimport
    - Override DllImport attribute name to
    \n\ - -namespace - Generate wrappers into C# namespace \n\ - -noproxy - Generate the low-level functional interface instead\n\ - of proxy classes\n\ - -oldvarnames - Old intermediary method names for variable wrappers\n\ - -csout - Write all C# to a single file located at \n\ + -dllimport
    - Override DllImport attribute name to
    \n\ + -namespace - Generate wrappers into C# namespace \n\ + -noproxy - Generate the low-level functional interface instead\n\ + of proxy classes\n\ + -oldvarnames - Old intermediary method names for variable wrappers\n\ + -outfile - Write all C# to a single file located in the output directory\n\ \n"; From 2b9b007027961cf79088af2f38398e8c33dc3c4c Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 11 Jun 2015 07:42:50 +0100 Subject: [PATCH 4/6] C# -outfile cosmetic code fixes --- Source/Modules/csharp.cxx | 57 +++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index ad27a5bea..38afc7357 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -248,16 +248,16 @@ public: } else if (strcmp(argv[i], "-oldvarnames") == 0) { Swig_mark_arg(i); old_variable_names = true; - } else if (strcmp(argv[i], "-outfile") == 0) { - if (argv[i + 1]) { - output_file = NewString(""); - Printf(output_file, argv[i + 1]); - Swig_mark_arg(i); - Swig_mark_arg(i + 1); - i++; - } else { - Swig_arg_error(); - } + } else if (strcmp(argv[i], "-outfile") == 0) { + if (argv[i + 1]) { + output_file = NewString(""); + Printf(output_file, argv[i + 1]); + Swig_mark_arg(i); + Swig_mark_arg(i + 1); + i++; + } else { + Swig_arg_error(); + } } else if (strcmp(argv[i], "-help") == 0) { Printf(stdout, "%s\n", usage); } @@ -465,7 +465,7 @@ public: Printf(f_im, "}\n"); addCloseNamespace(0, f_im); - if(f_im != f_single_out) + if (f_im != f_single_out) Delete(f_im); f_im = NULL; } @@ -508,7 +508,7 @@ public: Printf(f_module, "}\n"); addCloseNamespace(0, f_module); - if(f_module != f_single_out) + if (f_module != f_single_out) Delete(f_module); f_module = NULL; } @@ -609,7 +609,7 @@ public: f_directors_h = NULL; } - if(f_single_out) { + if (f_single_out) { Dump(f_single_out, f_begin); Delete(f_single_out); f_single_out = NULL; @@ -649,12 +649,12 @@ public: * /.cs * ----------------------------------------------------------------------------- */ - File *getOutputFile(const String* dir, String* name) { - if(output_file) { - if(!f_single_out) { + File *getOutputFile(const String *dir, const String *name) { + if (output_file) { + if (!f_single_out) { String *filen = NewStringf("%s%s", SWIG_output_directory(), output_file); f_single_out = NewFile(filen, "w", SWIG_output_files()); - if(!f_single_out) { + if (!f_single_out) { FileErrorDisplay(filen); SWIG_exit(EXIT_FAILURE); } @@ -668,7 +668,7 @@ public: } else { String *filen = NewStringf("%s%s.cs", dir, name); File *f = NewFile(filen, "w", SWIG_output_files()); - if(!f) { + if (!f) { FileErrorDisplay(f); SWIG_exit(EXIT_FAILURE); } @@ -1132,7 +1132,7 @@ public: scope = NewString(""); if (nspace) Printf(scope, "%s", nspace); - if (Node* cls = getCurrentClass()) { + if (Node *cls = getCurrentClass()) { if (Node *outer = Getattr(cls, "nested:outer")) { String *outerClassesPrefix = Copy(Getattr(outer, "sym:name")); for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) { @@ -1252,7 +1252,7 @@ public: "\n", enum_code, "\n", NIL); addCloseNamespace(nspace, f_enum); - if(f_enum != f_single_out) + if (f_enum != f_single_out) Delete(f_enum); f_enum = NULL; Delete(output_directory); @@ -1954,7 +1954,6 @@ public: } } - // Each outer proxy class goes into a separate file if (!has_outerclass) { String *output_directory = outputDirectory(nspace); f_proxy = getOutputFile(output_directory, proxy_class_name); @@ -2017,7 +2016,7 @@ public: if (!has_outerclass) { Printf(f_proxy, "}\n"); addCloseNamespace(nspace, f_proxy); - if(f_proxy != f_single_out) + if (f_proxy != f_single_out) Delete(f_proxy); f_proxy = NULL; } else { @@ -3278,7 +3277,7 @@ public: Printv(f_swigtype, swigtype, NIL); addCloseNamespace(0, f_swigtype); - if(f_swigtype != f_single_out) + if (f_swigtype != f_single_out) Delete(f_swigtype); f_swigtype = NULL; Delete(swigtype); @@ -4297,10 +4296,10 @@ extern "C" Language *swig_csharp(void) { const char *CSHARP::usage = "\ C# Options (available with -csharp)\n\ - -dllimport
    - Override DllImport attribute name to
    \n\ - -namespace - Generate wrappers into C# namespace \n\ - -noproxy - Generate the low-level functional interface instead\n\ - of proxy classes\n\ - -oldvarnames - Old intermediary method names for variable wrappers\n\ - -outfile - Write all C# to a single file located in the output directory\n\ + -dllimport
    - Override DllImport attribute name to
    \n\ + -namespace - Generate wrappers into C# namespace \n\ + -noproxy - Generate the low-level functional interface instead\n\ + of proxy classes\n\ + -oldvarnames - Old intermediary method names for variable wrappers\n\ + -outfile - Write all C# into a single located in the output directory\n\ \n"; From c1a18992ccc56bb85cb33e0a4e366608929b68de Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Thu, 11 Jun 2015 07:43:26 +0100 Subject: [PATCH 5/6] Add in all C# command line options to the docs --- Doc/Manual/CSharp.html | 66 +++++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html index 28d6d2b2e..0c0d98c0e 100644 --- a/Doc/Manual/CSharp.html +++ b/Doc/Manual/CSharp.html @@ -14,7 +14,7 @@
  • SWIG 2 Compatibility Differences to the Java module
  • Void pointers @@ -37,7 +37,7 @@
  • Directors implementation
  • Director caveats -
  • Multiples modules +
  • Multiple modules
  • C# Typemap examples