diff options
author | Derrick <a11426@users.sourceforge.net> | 2011-02-14 20:11:58 +0000 |
---|---|---|
committer | Derrick <a11426@users.sourceforge.net> | 2011-02-14 20:11:58 +0000 |
commit | 5815f7ec289e067e765fb8e893a2f337d8b48303 (patch) | |
tree | ebe9e0534a089fe431cedc6fdbc1a53ac523d70c /Examples/d | |
parent | 3e1af1f698d5d02d7905431bcb3549c0f7bc9aa7 (diff) | |
parent | 1fab53b2046b97702e1de4cfab06cb8fa8fc129d (diff) | |
download | swig-a11426-fortran.tar.gz |
update fortran branch. merge of 12160:12460a11426-fortran
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/a11426-fortran@12461 626c5289-ae23-0410-ae9c-e8d60b6d4f22
Diffstat (limited to 'Examples/d')
47 files changed, 1489 insertions, 0 deletions
diff --git a/Examples/d/callback/Makefile b/Examples/d/callback/Makefile new file mode 100644 index 000000000..b5808cf0d --- /dev/null +++ b/Examples/d/callback/Makefile @@ -0,0 +1,30 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_run diff --git a/Examples/d/callback/d1/runme.d b/Examples/d/callback/d1/runme.d new file mode 100644 index 000000000..e34e09603 --- /dev/null +++ b/Examples/d/callback/d1/runme.d @@ -0,0 +1,36 @@ +module runme; + +import tango.io.Stdout; +import example; + +public class DCallback : Callback { + public override void run() { + Stdout( "DCallback.run()" ).newline; + } +} + +void main() { + auto caller = new Caller(); + + Stdout( "Adding and calling a normal C++ callback" ).newline; + Stdout( "----------------------------------------" ).newline; + { + scope auto callback = new Callback(); + caller.setCallback(callback); + caller.call(); + caller.resetCallback(); + } + + Stdout.newline; + Stdout( "Adding and calling a D callback" ).newline; + Stdout( "-------------------------------" ).newline; + { + scope auto callback = new DCallback(); + caller.setCallback(callback); + caller.call(); + caller.resetCallback(); + } + + Stdout.newline; + Stdout( "D exit" ).newline; +} diff --git a/Examples/d/callback/d2/runme.d b/Examples/d/callback/d2/runme.d new file mode 100644 index 000000000..88ffcdefd --- /dev/null +++ b/Examples/d/callback/d2/runme.d @@ -0,0 +1,36 @@ +module runme; + +import std.stdio; +import example; + +public class DCallback : Callback { + public override void run() { + writeln( "DCallback.run()" ); + } +} + +void main() { + auto caller = new Caller(); + + writeln( "Adding and calling a normal C++ callback" ); + writeln( "----------------------------------------" ); + { + scope auto callback = new Callback(); + caller.setCallback(callback); + caller.call(); + caller.resetCallback(); + } + + writeln(); + writeln( "Adding and calling a D callback" ); + writeln( "-------------------------------" ); + { + scope auto callback = new DCallback(); + caller.setCallback(callback); + caller.call(); + caller.resetCallback(); + } + + writeln(); + writeln( "D exit" ); +} diff --git a/Examples/d/callback/example.cxx b/Examples/d/callback/example.cxx new file mode 100644 index 000000000..450d75608 --- /dev/null +++ b/Examples/d/callback/example.cxx @@ -0,0 +1,4 @@ +/* File : example.cxx */ + +#include "example.h" + diff --git a/Examples/d/callback/example.h b/Examples/d/callback/example.h new file mode 100644 index 000000000..38d25a043 --- /dev/null +++ b/Examples/d/callback/example.h @@ -0,0 +1,24 @@ +/* File : example.h */ + +#include <cstdio> +#include <iostream> + +class Callback { +public: + virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; } + virtual void run() { std::cout << "Callback::run()" << std::endl; } +}; + + +class Caller { +private: + Callback *_callback; +public: + Caller(): _callback(0) {} + ~Caller() { delCallback(); } + void delCallback() { delete _callback; _callback = 0; } + void setCallback(Callback *cb) { delCallback(); _callback = cb; } + void resetCallback() { _callback = 0; } + void call() { if (_callback) _callback->run(); } +}; + diff --git a/Examples/d/callback/example.i b/Examples/d/callback/example.i new file mode 100644 index 000000000..90beda01a --- /dev/null +++ b/Examples/d/callback/example.i @@ -0,0 +1,13 @@ +/* File : example.i */ +%module(directors="1") example +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* turn on director wrapping Callback */ +%feature("director") Callback; + +%include "example.h" + diff --git a/Examples/d/check.list b/Examples/d/check.list new file mode 100644 index 000000000..010e7bbfc --- /dev/null +++ b/Examples/d/check.list @@ -0,0 +1,9 @@ +# See top-level Makefile.in. +callback +class +constants +enum +extend +funcptr +simple +variables diff --git a/Examples/d/class/Makefile b/Examples/d/class/Makefile new file mode 100644 index 000000000..b5808cf0d --- /dev/null +++ b/Examples/d/class/Makefile @@ -0,0 +1,30 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_run diff --git a/Examples/d/class/d1/runme.d b/Examples/d/class/d1/runme.d new file mode 100644 index 000000000..b0c4263a2 --- /dev/null +++ b/Examples/d/class/d1/runme.d @@ -0,0 +1,58 @@ +// This example illustrates how C++ classes can be used from D using SWIG. +// The D class gets mapped onto the C++ class and behaves as if it is a D class. +module runme; + +import tango.io.Stdout; +import example; + +void main() { + // ----- Object creation ----- + + Stdout( "Creating some objects:" ).newline; + + { + scope Square s = new Square(10); + scope Circle c = new Circle(10); + + // ----- Access a static member ----- + Stdout.format( "{} shapes were created.", Shape.nshapes ).newline; + + // ----- Member data access ----- + + // Notice how we can do this using functions specific to + // the 'Circle' class. + c.x = 20; + c.y = 30; + + // Now use the same functions in the base class + Shape shape = s; + shape.x = -10; + shape.y = 5; + + Stdout( "\nHere is their current position:" ).newline; + Stdout.format( " Circle = ( {}, {} )", c.x, c.y ).newline; + Stdout.format( " Square = ( {}, {} )", s.x, s.y ).newline; + + // ----- Call some methods ----- + + Stdout( "\nHere are some properties of the shapes:" ).newline; + Shape[] shapes = [ cast(Shape) c, cast(Shape) s ]; + foreach ( currentShape; shapes ) + { + Stdout.format( " {}", currentShape.classinfo.name ).newline; + Stdout.format( " area = {}", currentShape.area() ).newline; + Stdout.format( " perimeter = {}", currentShape.perimeter() ).newline; + } + + // Notice how the area() and perimeter() functions really + // invoke the appropriate virtual method on each object. + + // ----- Delete everything ----- + Stdout( "\nGuess I'll clean up now:" ).newline; + // Note: when this using scope is exited the D destructors are called which + // in turn call the C++ destructors. + } + + Stdout.format( "{} shapes remain", Shape.nshapes ).newline; + Stdout( "\nGoodbye!" ).newline; +} diff --git a/Examples/d/class/d2/runme.d b/Examples/d/class/d2/runme.d new file mode 100644 index 000000000..2e86c5fc7 --- /dev/null +++ b/Examples/d/class/d2/runme.d @@ -0,0 +1,58 @@ +// This example illustrates how C++ classes can be used from D using SWIG. +// The D class gets mapped onto the C++ class and behaves as if it is a D class. +module runme; + +import std.stdio; +import example; + +void main() { + // ----- Object creation ----- + + writeln( "Creating some objects:" ); + + { + scope Square s = new Square(10); + scope Circle c = new Circle(10); + + // ----- Access a static member ----- + writefln( "%s shapes were created.", Shape.nshapes ); + + // ----- Member data access ----- + + // Notice how we can do this using functions specific to + // the 'Circle' class. + c.x = 20; + c.y = 30; + + // Now use the same functions in the base class + Shape shape = s; + shape.x = -10; + shape.y = 5; + + writeln( "\nHere is their current position:" ); + writefln( " Circle = ( %s, %s )", c.x, c.y ); + writefln( " Square = ( %s, %s )", s.x, s.y ); + + // ----- Call some methods ----- + + writeln( "\nHere are some properties of the shapes:" ); + Shape[] shapes = [ cast(Shape) c, cast(Shape) s ]; + foreach ( currentShape; shapes ) + { + writefln( " %s", currentShape.classinfo.name ); + writefln( " area = %s", currentShape.area() ); + writefln( " perimeter = %s", currentShape.perimeter() ); + } + + // Notice how the area() and perimeter() functions really + // invoke the appropriate virtual method on each object. + + // ----- Delete everything ----- + writeln( "\nGuess I'll clean up now:" ); + // Note: when this using scope is exited the D destructors are called which + // in turn call the C++ destructors. + } + + writefln( "%s shapes remain", Shape.nshapes ); + writeln( "\nGoodbye!" ); +} diff --git a/Examples/d/class/example.cxx b/Examples/d/class/example.cxx new file mode 100644 index 000000000..1e8e203dd --- /dev/null +++ b/Examples/d/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/d/class/example.h b/Examples/d/class/example.h new file mode 100644 index 000000000..0d4527e92 --- /dev/null +++ b/Examples/d/class/example.h @@ -0,0 +1,34 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; diff --git a/Examples/d/class/example.i b/Examples/d/class/example.i new file mode 100644 index 000000000..75700b305 --- /dev/null +++ b/Examples/d/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/d/constants/Makefile b/Examples/d/constants/Makefile new file mode 100644 index 000000000..412055243 --- /dev/null +++ b/Examples/d/constants/Makefile @@ -0,0 +1,30 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ example_wrap.c +EXTRA_LDFLAGS = example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_run diff --git a/Examples/d/constants/d1/runme.d b/Examples/d/constants/d1/runme.d new file mode 100644 index 000000000..47362cbf3 --- /dev/null +++ b/Examples/d/constants/d1/runme.d @@ -0,0 +1,28 @@ +module runme; + +import tango.io.Stdout; +static import example; + +void main() { + Stdout.formatln("ICONST = {} (should be 42)", example.ICONST); + Stdout.formatln("FCONST = {} (should be 2.18)", example.FCONST); + Stdout.formatln("CCONST = {} (should be 'x')", example.CCONST); + Stdout.formatln("CCONST2 = {} (this should be on a new line)", example.CCONST2); + Stdout.formatln("SCONST = {} (should be 'Hello World')", example.SCONST); + Stdout.formatln("SCONST2 = {} (should be '\"Hello World\"')", example.SCONST2); + Stdout.formatln("EXPR = {} (should be 48.55)", example.EXPR); + Stdout.formatln("iconst = {} (should be 37)", example.iconst); + Stdout.formatln("fconst = {} (should be 3.14)", example.fconst); + + static if (is(typeof(example.EXTERN))) { + Stdout.formatln("EXTERN should not be defined, but is: {}.", example.EXTERN ); + } else { + Stdout.formatln("EXTERN isn't defined (good)"); + } + + static if (is(typeof(example.FOO))) { + Stdout.formatln("FOO should not be defined, but is: {}.", example.FOO); + } else { + Stdout.formatln("FOO isn't defined (good)"); + } +} diff --git a/Examples/d/constants/d2/runme.d b/Examples/d/constants/d2/runme.d new file mode 100644 index 000000000..4be510d16 --- /dev/null +++ b/Examples/d/constants/d2/runme.d @@ -0,0 +1,28 @@ +module runme; + +import std.stdio; +static import example; + +void main() { + writefln("ICONST = %s (should be 42)", example.ICONST); + writefln("FCONST = %s (should be 2.1828)", example.FCONST); + writefln("CCONST = %s (should be 'x')", example.CCONST); + writefln("CCONST2 = %s (this should be on a new line)", example.CCONST2); + writefln("SCONST = %s (should be 'Hello World')", example.SCONST); + writefln("SCONST2 = %s (should be '\"Hello World\"')", example.SCONST2); + writefln("EXPR = %s (should be 48.5484)", example.EXPR); + writefln("iconst = %s (should be 37)", example.iconst); + writefln("fconst = %s (should be 3.14)", example.fconst); + + static if (is(typeof(example.EXTERN))) { + writefln("EXTERN should not be defined, but is: %s.", example.EXTERN ); + } else { + writeln("EXTERN isn't defined (good)"); + } + + static if (is(typeof(example.FOO))) { + writefln("FOO should not be defined, but is: %s.", example.FOO); + } else { + writeln("FOO isn't defined (good)"); + } +} diff --git a/Examples/d/constants/example.d b/Examples/d/constants/example.d new file mode 100644 index 000000000..7448d0ad9 --- /dev/null +++ b/Examples/d/constants/example.d @@ -0,0 +1,23 @@ +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.41 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +module example; + +static import example_wrap; + +static import tango.stdc.stringz; + +public const int ICONST = 42; +public const double FCONST = 2.1828; +public const char CCONST = 'x'; +public const char CCONST2 = '\n'; +public const char[] SCONST = "Hello World"; +public const char[] SCONST2 = "\"Hello World\""; +public const double EXPR = 42+3*(2.1828); +public const int iconst = 37; +public const double fconst = 3.14; diff --git a/Examples/d/constants/example.i b/Examples/d/constants/example.i new file mode 100644 index 000000000..edeb258cd --- /dev/null +++ b/Examples/d/constants/example.i @@ -0,0 +1,32 @@ +/* File : example.i */ +%module example + +/* Force the generated D code to use the C constant values rather than + retrieving them at runtime. You can also try disabling the feature and + compare the generated code. */ +%dmanifestconst; + + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + + +/* The following directives also produce constants */ + +%constant int iconst = 37; +%constant double fconst = 3.14; diff --git a/Examples/d/enum/Makefile b/Examples/d/enum/Makefile new file mode 100644 index 000000000..b5808cf0d --- /dev/null +++ b/Examples/d/enum/Makefile @@ -0,0 +1,30 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_run diff --git a/Examples/d/enum/d1/runme.d b/Examples/d/enum/d1/runme.d new file mode 100644 index 000000000..d986986d1 --- /dev/null +++ b/Examples/d/enum/d1/runme.d @@ -0,0 +1,28 @@ +module runme; + +import tango.io.Stdout; +import example; + +void main() { + Stdout( "Printing out some enum values:" ).newline; + Stdout(" color:").newline; + Stdout.formatln(" {} = {}", color.RED, cast(int)color.RED); + Stdout.formatln(" {} = {}", color.BLUE, cast(int)color.BLUE); + Stdout.formatln(" {} = {}", color.GREEN, cast(int)color.GREEN); + + Stdout("\n Foo.speed:").newline; + Stdout.formatln(" Foo.{} = {}", Foo.speed.IMPULSE, cast(int)Foo.speed.IMPULSE); + Stdout.formatln(" Foo.{} = {}", Foo.speed.WARP, cast(int)Foo.speed.WARP); + Stdout.formatln(" Foo.{} = {}", Foo.speed.LUDICROUS , cast(int)Foo.speed.LUDICROUS); + + Stdout("\nTesting use of enums with functions:").newline; + example.enum_test(color.RED, Foo.speed.IMPULSE); + example.enum_test(color.BLUE, Foo.speed.WARP); + example.enum_test(color.GREEN, Foo.speed.LUDICROUS); + + Stdout( "\nTesting use of enum with class method:" ).newline; + scope f = new Foo(); + f.enum_test(Foo.speed.IMPULSE); + f.enum_test(Foo.speed.WARP); + f.enum_test(Foo.speed.LUDICROUS); +} diff --git a/Examples/d/enum/d2/runme.d b/Examples/d/enum/d2/runme.d new file mode 100644 index 000000000..acaec8ae8 --- /dev/null +++ b/Examples/d/enum/d2/runme.d @@ -0,0 +1,28 @@ +module runme; + +import std.stdio; +import example; + +void main() { + writeln( "Printing out some enum values:" ); + writeln(" color:"); + writefln(" %s = %s", color.RED, cast(int)color.RED); + writefln(" %s = %s", color.BLUE, cast(int)color.BLUE); + writefln(" %s = %s", color.GREEN, cast(int)color.GREEN); + + writeln("\n Foo.speed:"); + writefln(" Foo.%s = %s", Foo.speed.IMPULSE, cast(int)Foo.speed.IMPULSE); + writefln(" Foo.%s = %s", Foo.speed.WARP, cast(int)Foo.speed.WARP); + writefln(" Foo.%s = %s", Foo.speed.LUDICROUS , cast(int)Foo.speed.LUDICROUS); + + writeln("\nTesting use of enums with functions:"); + example.enum_test(color.RED, Foo.speed.IMPULSE); + example.enum_test(color.BLUE, Foo.speed.WARP); + example.enum_test(color.GREEN, Foo.speed.LUDICROUS); + + writeln( "\nTesting use of enum with class method:" ); + scope f = new Foo(); + f.enum_test(Foo.speed.IMPULSE); + f.enum_test(Foo.speed.WARP); + f.enum_test(Foo.speed.LUDICROUS); +} diff --git a/Examples/d/enum/example.cxx b/Examples/d/enum/example.cxx new file mode 100644 index 000000000..df7bb6328 --- /dev/null +++ b/Examples/d/enum/example.cxx @@ -0,0 +1,37 @@ +/* File : example.cxx */ + +#include "example.h" +#include <stdio.h> + +void Foo::enum_test(speed s) { + if (s == IMPULSE) { + printf("IMPULSE speed\n"); + } else if (s == WARP) { + printf("WARP speed\n"); + } else if (s == LUDICROUS) { + printf("LUDICROUS speed\n"); + } else { + printf("Unknown speed\n"); + } +} + +void enum_test(color c, Foo::speed s) { + if (c == RED) { + printf("color = RED, "); + } else if (c == BLUE) { + printf("color = BLUE, "); + } else if (c == GREEN) { + printf("color = GREEN, "); + } else { + printf("color = Unknown color!, "); + } + if (s == Foo::IMPULSE) { + printf("speed = IMPULSE speed\n"); + } else if (s == Foo::WARP) { + printf("speed = WARP speed\n"); + } else if (s == Foo::LUDICROUS) { + printf("speed = LUDICROUS speed\n"); + } else { + printf("speed = Unknown speed!\n"); + } +} diff --git a/Examples/d/enum/example.h b/Examples/d/enum/example.h new file mode 100644 index 000000000..9119cd9fc --- /dev/null +++ b/Examples/d/enum/example.h @@ -0,0 +1,13 @@ +/* File : example.h */ + +enum color { RED, BLUE, GREEN }; + +class Foo { + public: + Foo() { } + enum speed { IMPULSE=10, WARP=20, LUDICROUS=30 }; + void enum_test(speed s); +}; + +void enum_test(color c, Foo::speed s); + diff --git a/Examples/d/enum/example.i b/Examples/d/enum/example.i new file mode 100644 index 000000000..23ee8a822 --- /dev/null +++ b/Examples/d/enum/example.i @@ -0,0 +1,11 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ + +%include "example.h" + diff --git a/Examples/d/extend/Makefile b/Examples/d/extend/Makefile new file mode 100644 index 000000000..b5808cf0d --- /dev/null +++ b/Examples/d/extend/Makefile @@ -0,0 +1,30 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.cxx example_wrap.cxx +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d_cpp; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_run diff --git a/Examples/d/extend/d1/runme.d b/Examples/d/extend/d1/runme.d new file mode 100644 index 000000000..96501d1a4 --- /dev/null +++ b/Examples/d/extend/d1/runme.d @@ -0,0 +1,75 @@ +/// This file illustrates the cross language polymorphism using directors. +module runme; + +import example; +import tango.io.Stdout; + +// CEO class, which overrides Employee.getPosition(). +class CEO : Manager { +public: + this( char[] name ) { + super( name ); + } + + override char[] getPosition() { + return "CEO"; + } + + // Public method to stop the SWIG proxy base class from thinking it owns the underlying C++ memory. + void disownMemory() { + swigCMemOwn = false; + } +} + +void main() { + // Create an instance of CEO, a class derived from the D proxy of the + // underlying C++ class. The calls to getName() and getPosition() are standard, + // the call to getTitle() uses the director wrappers to call CEO.getPosition(). + + auto e = new CEO( "Alice" ); + Stdout.formatln( "{} is a {}.", e.getName(), e.getPosition() ); + Stdout.formatln( "Just call her '{}'.", e.getTitle() ); + Stdout( "----------------------" ).newline; + + { + // Create a new EmployeeList instance. This class does not have a C++ + // director wrapper, but can be used freely with other classes that do. + scope auto list = new EmployeeList(); + + // EmployeeList owns its items, so we must surrender ownership of objects we add. + e.disownMemory(); + list.addEmployee(e); + Stdout( "----------------------" ).newline; + + // Now we access the first four items in list (three are C++ objects that + // EmployeeList's constructor adds, the last is our CEO). The virtual + // methods of all these instances are treated the same. For items 0, 1, and + // 2, all methods resolve in C++. For item 3, our CEO, getTitle calls + // getPosition which resolves in D. The call to getPosition is + // slightly different, however, because of the overidden getPosition() call, since + // now the object reference has been "laundered" by passing through + // EmployeeList as an Employee*. Previously, D resolved the call + // immediately in CEO, but now D thinks the object is an instance of + // class Employee. So the call passes through the + // Employee proxy class and on to the C wrappers and C++ director, + // eventually ending up back at the D CEO implementation of getPosition(). + // The call to getTitle() for item 3 runs the C++ Employee::getTitle() + // method, which in turn calls getPosition(). This virtual method call + // passes down through the C++ director class to the D implementation + // in CEO. All this routing takes place transparently. + + Stdout( "(position, title) for items 0-3:" ).newline; + Stdout.formatln( " {}, '{}'", list.getItem(0).getPosition(), list.getItem(0).getTitle() ); + Stdout.formatln( " {}, '{}'", list.getItem(1).getPosition(), list.getItem(1).getTitle() ); + Stdout.formatln( " {}, '{}'", list.getItem(2).getPosition(), list.getItem(2).getTitle() ); + Stdout.formatln( " {}, '{}'", list.getItem(3).getPosition(), list.getItem(3).getTitle() ); + Stdout( "----------------------" ).newline; + + // All Employees will be destroyed when the EmployeeList goes out of scope, + // including the CEO instance. + } + Stdout( "----------------------" ).newline; + + // All done. + Stdout( "Exiting cleanly from D code." ).newline; +} diff --git a/Examples/d/extend/d2/runme.d b/Examples/d/extend/d2/runme.d new file mode 100644 index 000000000..1ea6dfd21 --- /dev/null +++ b/Examples/d/extend/d2/runme.d @@ -0,0 +1,75 @@ +/// This file illustrates the cross language polymorphism using directors. +module runme; + +import std.stdio; +import example; + +// CEO class, which overrides Employee.getPosition(). +class CEO : Manager { +public: + this( string name ) { + super( name ); + } + + override string getPosition() const { + return "CEO"; + } + + // Public method to stop the SWIG proxy base class from thinking it owns the underlying C++ memory. + void disownMemory() { + swigCMemOwn = false; + } +} + +void main() { + // Create an instance of CEO, a class derived from the D proxy of the + // underlying C++ class. The calls to getName() and getPosition() are standard, + // the call to getTitle() uses the director wrappers to call CEO.getPosition(). + + auto e = new CEO( "Alice" ); + writefln( "%s is a %s.", e.getName(), e.getPosition() ); + writefln( "Just call her '%s'.", e.getTitle() ); + writeln( "----------------------" ); + + { + // Create a new EmployeeList instance. This class does not have a C++ + // director wrapper, but can be used freely with other classes that do. + scope auto list = new EmployeeList(); + + // EmployeeList owns its items, so we must surrender ownership of objects we add. + e.disownMemory(); + list.addEmployee(e); + writeln( "----------------------" ); + + // Now we access the first four items in list (three are C++ objects that + // EmployeeList's constructor adds, the last is our CEO). The virtual + // methods of all these instances are treated the same. For items 0, 1, and + // 2, all methods resolve in C++. For item 3, our CEO, getTitle calls + // getPosition which resolves in D. The call to getPosition is + // slightly different, however, because of the overidden getPosition() call, since + // now the object reference has been "laundered" by passing through + // EmployeeList as an Employee*. Previously, D resolved the call + // immediately in CEO, but now D thinks the object is an instance of + // class Employee. So the call passes through the + // Employee proxy class and on to the C wrappers and C++ director, + // eventually ending up back at the D CEO implementation of getPosition(). + // The call to getTitle() for item 3 runs the C++ Employee::getTitle() + // method, which in turn calls getPosition(). This virtual method call + // passes down through the C++ director class to the D implementation + // in CEO. All this routing takes place transparently. + + writeln( "(position, title) for items 0-3:" ); + writefln( " %s, '%s'", list.getItem(0).getPosition(), list.getItem(0).getTitle() ); + writefln( " %s, '%s'", list.getItem(1).getPosition(), list.getItem(1).getTitle() ); + writefln( " %s, '%s'", list.getItem(2).getPosition(), list.getItem(2).getTitle() ); + writefln( " %s, '%s'", list.getItem(3).getPosition(), list.getItem(3).getTitle() ); + writeln( "----------------------" ); + + // All Employees will be destroyed when the EmployeeList goes out of scope, + // including the CEO instance. + } + writeln( "----------------------" ); + + // All done. + writeln( "Exiting cleanly from D code." ); +} diff --git a/Examples/d/extend/example.cxx b/Examples/d/extend/example.cxx new file mode 100644 index 000000000..450d75608 --- /dev/null +++ b/Examples/d/extend/example.cxx @@ -0,0 +1,4 @@ +/* File : example.cxx */ + +#include "example.h" + diff --git a/Examples/d/extend/example.h b/Examples/d/extend/example.h new file mode 100644 index 000000000..7ad93fbc1 --- /dev/null +++ b/Examples/d/extend/example.h @@ -0,0 +1,56 @@ +/* File : example.h */ + +#include <cstdio> +#include <iostream> +#include <vector> +#include <string> +#include <cmath> + +class Employee { +private: + std::string name; +public: + Employee(const char* n): name(n) {} + virtual std::string getTitle() { return getPosition() + " " + getName(); } + virtual std::string getName() { return name; } + virtual std::string getPosition() const { return "Employee"; } + virtual ~Employee() { printf("~Employee() @ %p\n", this); } +}; + + +class Manager: public Employee { +public: + Manager(const char* n): Employee(n) {} + virtual std::string getPosition() const { return "Manager"; } +}; + + +class EmployeeList { + std::vector<Employee*> list; +public: + EmployeeList() { + list.push_back(new Employee("Bob")); + list.push_back(new Employee("Jane")); + list.push_back(new Manager("Ted")); + } + void addEmployee(Employee *p) { + list.push_back(p); + std::cout << "New employee added. Current employees are:" << std::endl; + std::vector<Employee*>::iterator i; + for (i=list.begin(); i!=list.end(); i++) { + std::cout << " " << (*i)->getTitle() << std::endl; + } + } + const Employee *getItem(int i) { + return list[i]; + } + ~EmployeeList() { + std::vector<Employee*>::iterator i; + std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl; + for (i=list.begin(); i!=list.end(); i++) { + delete *i; + } + std::cout << "~EmployeeList empty." << std::endl; + } +}; + diff --git a/Examples/d/extend/example.i b/Examples/d/extend/example.i new file mode 100644 index 000000000..0647e1319 --- /dev/null +++ b/Examples/d/extend/example.i @@ -0,0 +1,14 @@ +/* File : example.i */ +%module(directors="1") example +%{ +#include "example.h" +%} + +%include "std_string.i" + +/* turn on director wrapping for Manager */ +%feature("director") Employee; +%feature("director") Manager; + +%include "example.h" + diff --git a/Examples/d/funcptr/Makefile b/Examples/d/funcptr/Makefile new file mode 100644 index 000000000..09efa8d88 --- /dev/null +++ b/Examples/d/funcptr/Makefile @@ -0,0 +1,30 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.c example_wrap.c +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_run diff --git a/Examples/d/funcptr/d1/runme.d b/Examples/d/funcptr/d1/runme.d new file mode 100644 index 000000000..1461c1546 --- /dev/null +++ b/Examples/d/funcptr/d1/runme.d @@ -0,0 +1,42 @@ +module runme; + +import tango.io.Stdout; +static import example; + +extern(C) int add(int a, int b) { + return a + b; +} + +extern(C) int sub(int a, int b) { + return a - b; +} + +extern(C) int mul(int a, int b) { + return a * b; +} + +void main() { + int a = 37; + int b = 42; + + Stdout( "a = " )( a ).newline; + Stdout( "b = " )( b ).newline; + + Stdout( "Trying some C callback functions:" ).newline; + Stdout( " ADD(a,b) = " )( example.do_op( a, b, example.ADD ) ).newline; + Stdout( " SUB(a,b) = " )( example.do_op( a, b, example.SUB ) ).newline; + Stdout( " MUL(a,b) = " )( example.do_op( a, b, example.MUL ) ).newline; + + version (LDC) { + // Currently, there is no way to specify the calling convention for + // function pointer parameters in D, but LDC does strict typechecking for + // them (which is reasonable, but not covered by the language spec yet). + // As a result, there is no way to make the code below compile with LDC at + // the moment, so just skip it. + } else { + Stdout( "Now the same with callback functions defined in D:" ).newline; + Stdout( " add(a,b) = " )( example.do_op( a, b, &add ) ).newline; + Stdout( " sub(a,b) = " )( example.do_op( a, b, &sub ) ).newline; + Stdout( " mul(a,b) = " )( example.do_op( a, b, &mul ) ).newline; + } +} diff --git a/Examples/d/funcptr/d2/runme.d b/Examples/d/funcptr/d2/runme.d new file mode 100644 index 000000000..929911d6c --- /dev/null +++ b/Examples/d/funcptr/d2/runme.d @@ -0,0 +1,34 @@ +module runme; + +import std.stdio; +static import example; + +extern(C) int add(int a, int b) { + return a + b; +} + +extern(C) int sub(int a, int b) { + return a - b; +} + +extern(C) int mul(int a, int b) { + return a * b; +} + +void main() { + int a = 37; + int b = 42; + + writefln( "a = %s", a ); + writefln( "b = %s", b ); + + writeln( "Trying some C callback functions:" ); + writefln( " ADD(a,b) = %s", example.do_op( a, b, example.ADD ) ); + writefln( " SUB(a,b) = %s", example.do_op( a, b, example.SUB ) ); + writefln( " MUL(a,b) = %s", example.do_op( a, b, example.MUL ) ); + + writeln( "Now the same with callback functions defined in D:" ); + writefln( " add(a,b) = %s", example.do_op( a, b, &add ) ); + writefln( " sub(a,b) = %s", example.do_op( a, b, &sub ) ); + writefln( " mul(a,b) = %s", example.do_op( a, b, &mul ) ); +} diff --git a/Examples/d/funcptr/example.c b/Examples/d/funcptr/example.c new file mode 100644 index 000000000..5c4a3dabf --- /dev/null +++ b/Examples/d/funcptr/example.c @@ -0,0 +1,19 @@ +/* File : example.c */ + +int do_op(int a, int b, int (*op)(int,int)) { + return (*op)(a,b); +} + +int add(int a, int b) { + return a+b; +} + +int sub(int a, int b) { + return a-b; +} + +int mul(int a, int b) { + return a*b; +} + +int (*funcvar)(int,int) = add; diff --git a/Examples/d/funcptr/example.h b/Examples/d/funcptr/example.h new file mode 100644 index 000000000..9936e24fc --- /dev/null +++ b/Examples/d/funcptr/example.h @@ -0,0 +1,9 @@ +/* file: example.h */ + +extern int do_op(int,int, int (*op)(int,int)); +extern int add(int,int); +extern int sub(int,int); +extern int mul(int,int); + +extern int (*funcvar)(int,int); + diff --git a/Examples/d/funcptr/example.i b/Examples/d/funcptr/example.i new file mode 100644 index 000000000..8b3bef678 --- /dev/null +++ b/Examples/d/funcptr/example.i @@ -0,0 +1,16 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Wrap a function taking a pointer to a function */ +extern int do_op(int a, int b, int (*op)(int, int)); + +/* Now install a bunch of "ops" as constants */ +%constant int (*ADD)(int,int) = add; +%constant int (*SUB)(int,int) = sub; +%constant int (*MUL)(int,int) = mul; + +extern int (*funcvar)(int,int); + diff --git a/Examples/d/simple/Makefile b/Examples/d/simple/Makefile new file mode 100644 index 000000000..ae173a566 --- /dev/null +++ b/Examples/d/simple/Makefile @@ -0,0 +1,30 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.c example_wrap.c +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_run diff --git a/Examples/d/simple/d1/runme.d b/Examples/d/simple/d1/runme.d new file mode 100644 index 000000000..1293f1839 --- /dev/null +++ b/Examples/d/simple/d1/runme.d @@ -0,0 +1,27 @@ +module runme; + +import tango.io.Stdout; +static import example; + +void main() { + /* + * Call our gcd() function. + */ + int x = 42; + int y = 105; + int g = example.gcd( x, y ); + Stdout.format( "The gcd of {} and {} is {}.", x, y, g ).newline; + + /* + * Manipulate the Foo global variable. + */ + + // Output its current value + Stdout.format( "Foo = {}", example.Foo ).newline; + + // Change its value + example.Foo = 3.1415926; + + // See if the change took effect + Stdout.format( "Foo = {}", example.Foo ).newline; +} diff --git a/Examples/d/simple/d2/runme.d b/Examples/d/simple/d2/runme.d new file mode 100644 index 000000000..7f278923b --- /dev/null +++ b/Examples/d/simple/d2/runme.d @@ -0,0 +1,27 @@ +module runme; + +import std.stdio; +static import example; + +void main() { + /* + * Call our gcd() function. + */ + int x = 42; + int y = 105; + int g = example.gcd(x, y); + writefln("The gcd of %s and %s is %s.", x, y, g); + + /* + * Manipulate the Foo global variable. + */ + + // Output its current value + writefln("Foo = %s", example.Foo); + + // Change its value + example.Foo = 3.1415926; + + // See if the change took effect + writefln("Foo = %s", example.Foo); +} diff --git a/Examples/d/simple/example.c b/Examples/d/simple/example.c new file mode 100644 index 000000000..1c2af789c --- /dev/null +++ b/Examples/d/simple/example.c @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/Examples/d/simple/example.i b/Examples/d/simple/example.i new file mode 100644 index 000000000..24093b9bf --- /dev/null +++ b/Examples/d/simple/example.i @@ -0,0 +1,7 @@ +/* File : example.i */ +%module example + +%inline %{ +extern int gcd(int x, int y); +extern double Foo; +%} diff --git a/Examples/d/variables/Makefile b/Examples/d/variables/Makefile new file mode 100644 index 000000000..ae173a566 --- /dev/null +++ b/Examples/d/variables/Makefile @@ -0,0 +1,30 @@ +ifeq (2,$(D_VERSION)) + WORKING_DIR = d2/ +else + WORKING_DIR = d1/ +endif + +TOP = ../../.. +SWIG = $(TOP)/../preinst-swig +EXTRA_CFLAGS = -I../ ../example.c example_wrap.c +EXTRA_LDFLAGS = example.o example_wrap.o +TARGET = example_wrap +SWIGOPT = +DSRCS = *.d +DFLAGS = -ofrunme + + +all:: d + +d:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT) -outcurrentdir ../example.i' TARGET='$(TARGET)' d; \ + $(MAKE) -f $(TOP)/Makefile DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile + +clean:: + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_clean + +check: all + cd $(WORKING_DIR); \ + $(MAKE) -f $(TOP)/Makefile d_run diff --git a/Examples/d/variables/d1/runme.d b/Examples/d/variables/d1/runme.d new file mode 100644 index 000000000..35c896bdc --- /dev/null +++ b/Examples/d/variables/d1/runme.d @@ -0,0 +1,71 @@ +// This example illustrates global variable access from C#. +module runme; + +import tango.io.Stdout; +static import example; + +void main() { + // Try to set the values of some global variables + example.ivar = 42; + example.svar = -31000; + example.lvar = 65537; + example.uivar = 123456; + example.usvar = 61000; + example.ulvar = 654321; + example.scvar = -13; + example.ucvar = 251; + example.cvar = 'S'; + example.fvar = 3.14159f; + example.dvar = 2.1828; + example.strvar = "Hello World"; + example.iptrvar = example.new_int(37); + example.ptptr = example.new_Point(37,42); + example.name = "Bill"; + + // Now print out the values of the variables + Stdout.formatln( "Variables (printed from D):" ); + Stdout.formatln( "ivar = {}", example.ivar ); + Stdout.formatln( "svar = {}", example.svar ); + Stdout.formatln( "lvar = {}", example.lvar ); + Stdout.formatln( "uivar = {}", example.uivar ); + Stdout.formatln( "usvar = {}", example.usvar ); + Stdout.formatln( "ulvar = {}", example.ulvar ); + Stdout.formatln( "scvar = {}", example.scvar ); + Stdout.formatln( "ucvar = {}", example.ucvar ); + Stdout.formatln( "fvar = {}", example.fvar ); + Stdout.formatln( "dvar = {}", example.dvar ); + Stdout.formatln( "cvar = {}", example.cvar ); + Stdout.formatln( "strvar = {}", example.strvar ); + Stdout.formatln( "cstrvar = {}", example.cstrvar ); + Stdout.formatln( "iptrvar = {}", example.iptrvar ); + Stdout.formatln( "name = {}", example.name ); + Stdout.formatln( "ptptr = {} {}", example.ptptr, example.Point_print(example.ptptr) ); + Stdout.formatln( "pt = {} {}", example.pt, example.Point_print(example.pt) ); + Stdout.formatln( "status = {}", example.status ); + + Stdout.formatln( "\nVariables (printed from the C library):" ); + example.print_vars(); + + Stdout.formatln( "\nNow I'm going to try and modify some read only variables:" ); + Stdout.formatln( "Checking that the read only variables are readonly..." ); + + Stdout( " 'path'..." ); + static if ( is( typeof( example.path = "a" ) ) ) + Stdout.formatln("Oh dear, this variable is not read only!"); + else + Stdout.formatln("Good."); + + Stdout( " 'status'..." ); + static if ( is( typeof( example.status = 2 ) ) ) + Stdout.formatln("Oh dear, this variable is not read only!"); + else + Stdout.formatln("Good."); + + Stdout.formatln( "\nI'm going to try and update a structure variable:" ); + + example.pt = example.ptptr; + + Stdout( "The new value is " ).flush; + example.pt_print(); + Stdout.formatln( "You should see the value {}", example.Point_print(example.ptptr) ); +} diff --git a/Examples/d/variables/d2/runme.d b/Examples/d/variables/d2/runme.d new file mode 100644 index 000000000..f80b81819 --- /dev/null +++ b/Examples/d/variables/d2/runme.d @@ -0,0 +1,71 @@ +// This example illustrates global variable access from C#. +module runme; + +import std.stdio; +static import example; + +void main() { + // Try to set the values of some global variables + example.ivar = 42; + example.svar = -31000; + example.lvar = 65537; + example.uivar = 123456; + example.usvar = 61000; + example.ulvar = 654321; + example.scvar = -13; + example.ucvar = 251; + example.cvar = 'S'; + example.fvar = 3.14159f; + example.dvar = 2.1828; + example.strvar = "Hello World"; + example.iptrvar = example.new_int(37); + example.ptptr = example.new_Point(37,42); + example.name = "Bill"; + + // Now print out the values of the variables + writefln( "Variables (printed from D):" ); + writefln( "ivar = %s", example.ivar ); + writefln( "svar = %s", example.svar ); + writefln( "lvar = %s", example.lvar ); + writefln( "uivar = %s", example.uivar ); + writefln( "usvar = %s", example.usvar ); + writefln( "ulvar = %s", example.ulvar ); + writefln( "scvar = %s", example.scvar ); + writefln( "ucvar = %s", example.ucvar ); + writefln( "fvar = %s", example.fvar ); + writefln( "dvar = %s", example.dvar ); + writefln( "cvar = %s", example.cvar ); + writefln( "strvar = %s", example.strvar ); + writefln( "cstrvar = %s", example.cstrvar ); + writefln( "iptrvar = %s", example.iptrvar ); + writefln( "name = %s", example.name ); + writefln( "ptptr = %s %s", example.ptptr, example.Point_print(example.ptptr) ); + writefln( "pt = %s %s", example.pt, example.Point_print(example.pt) ); + writefln( "status = %s", example.status ); + + writefln( "\nVariables (printed from the C library):" ); + example.print_vars(); + + writefln( "\nNow I'm going to try and modify some read only variables:" ); + writefln( "Checking that the read only variables are readonly..." ); + + writeln( " 'path'..." ); + static if ( is( typeof( example.path = "a" ) ) ) + writefln("Oh dear, this variable is not read only!"); + else + writefln("Good."); + + writeln( " 'status'..." ); + static if ( is( typeof( example.status = 2 ) ) ) + writefln("Oh dear, this variable is not read only!"); + else + writefln("Good."); + + writefln( "\nI'm going to try and update a structure variable:" ); + + example.pt = example.ptptr; + + write( "The new value is " ); + example.pt_print(); + writefln( "You should see the value %s", example.Point_print(example.ptptr) ); +} diff --git a/Examples/d/variables/example.c b/Examples/d/variables/example.c new file mode 100644 index 000000000..1bf9c120f --- /dev/null +++ b/Examples/d/variables/example.c @@ -0,0 +1,91 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include <stdio.h> +#include <stdlib.h> +#include "example.h" + +int ivar = 0; +short svar = 0; +long lvar = 0; +unsigned int uivar = 0; +unsigned short usvar = 0; +unsigned long ulvar = 0; +signed char scvar = 0; +unsigned char ucvar = 0; +char cvar = 0; +float fvar = 0; +double dvar = 0; +char *strvar = 0; +const char cstrvar[] = "Goodbye"; +int *iptrvar = 0; +char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; + +/* A variable that we will make read-only in the interface */ +int status = 1; + +/* A debugging function to print out their values */ + +void print_vars() { + printf("ivar = %d\n", ivar); + printf("svar = %d\n", svar); + printf("lvar = %ld\n", lvar); + printf("uivar = %u\n", uivar); + printf("usvar = %u\n", usvar); + printf("ulvar = %lu\n", ulvar); + printf("scvar = %d\n", scvar); + printf("ucvar = %u\n", ucvar); + printf("fvar = %g\n", fvar); + printf("dvar = %g\n", dvar); + printf("cvar = %c\n", cvar); + printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); + printf("iptrvar = %p\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); + printf("status = %d\n", status); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = value; + return ip; +} + +/* A function to create a point */ + +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d, %d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/d/variables/example.h b/Examples/d/variables/example.h new file mode 100644 index 000000000..0f7e89594 --- /dev/null +++ b/Examples/d/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/d/variables/example.i b/Examples/d/variables/example.i new file mode 100644 index 000000000..591b871ed --- /dev/null +++ b/Examples/d/variables/example.i @@ -0,0 +1,49 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Some global variable declarations */ +%inline %{ +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char cstrvar[]; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; +%} + + +/* Some read-only variables */ + +%immutable; + +%inline %{ +extern int status; +extern char path[256]; +%} + +%mutable; + +/* Some helper functions to make it easier to test */ +%inline %{ +extern void print_vars(); +extern int *new_int(int value); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); +%} + |