Dwith Swig / Examples /
Class
Difference (previous author) (Change, Edit, normal page display)
Changed: 1c1,248
Describe the new page here. |
[[toc]] === Wrap a C++ class === This example is adapted from the SWIG examples === Code to be wrapped === There are two files, the header file example.h and the function bodies example.cxx. example.h [[code] /* File : example.h */ class Shape { /* The member objects have been moved to private * because of problems with the SWIG translation * generating a wrapper code which will not compile * without alteration */ private: double x, y; static int nshapes; public: Shape() { nshapes++; x = 0; y = 0; } virtual ~Shape() { nshapes--; }; void move(double dx, double dy); /* Added member functions to get the value back */ double x_get() { return x; } double y_get() { return y; } virtual double area(void) = 0; virtual double perimeter(void) = 0; }; class Circle : public Shape { private: double radius; public: Circle(double r) : radius(r) { }; double radius_get() { return radius; } virtual double area(void); virtual double perimeter(void); }; class Square : public Shape { private: double width; public: Square(double w) : width(w) { }; double width_get() { return width; } virtual double area(void); virtual double perimeter(void); }; ] example.cxx [[code] /* File : example.cxx */ #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; } ] === Interface file === The interface file for this is quite simple, as it just uses the header file for the class. This is the real key to work with SWIG and C++ code. example.i [[code] /* File : example.i */ %module example /* Any section like this is transferred to the wrapper file, so that the wrapper code will contain the header. */ %{ #include "example.h" %} /* Let's just grab the original header file here */ %include "example.h" ] === Run SWIG === [[code] swig -dmd -c++ example.i ] Note the added parameter c++. This generates the following files: * example.d * classCircle.d * classSquare.d * classShape.d * examplePINVOKE.d * example_wrap.cxx In this case example.d is empty as there are no C++ functions to be wrapped which are not in a class. The interface to the D language is by calls to the D classes in the files with names starting class. These call functions in examplePINVOKE.d which uses C linkage to call example_wrap.cxx, so making the interface possible. === Example Application === helloex.d [[code] /* Example for testing the D interface to a C++ class */ /* private import example; */ private import classCircle; private import classSquare; /* hello.d from the dmd distribution adapted as an example for D SWIG */ /* for C++ extensions it is necessary to link the C++ run time */ /* This can be done by compiling the D files first e.g. */ /* swig -dmd -c++ example.i */ /* dmd -c helloex.d */ /* dmd -c classCircle.d */ /* dmd -c classSquare.d */ /* dmd -c classShape.d */ /* g++ -c example_wrap.cxx */ /* g++ -c example.cxx */ /* g++ helloex.o -ohelloex classCircle.o classSquare.o classShape.o * example_wrap.o example.o * -lphobos -lpthread -lm */ int main(char[][] args) { printf("hello world\n"); printf("\nTesting interface to a C++ class\n\n"); /* Note how to declare new objects */ printf("Declare:\n"); printf("Circle circle = new Circle(10.);\n"); Circle circle = new Circle(10.); printf("circle has radius %lf\n",circle.radius_get()); printf("circle has perimeter %lf\n",circle.perimeter()); printf("circle has area %lf\n",circle.area()); printf("\nDeclare:\n"); printf("Square square = new Square(10.);\n"); Square square = new Square(10.); printf("square has width %lf\n",square.width_get()); printf("square has perimeter %lf\n",square.perimeter()); printf("square has area %lf\n",square.area()); printf("\nTesting inherited functions\n\n"); printf("square is at (%lf,%lf)\n",square.x_get(),square.y_get()); square.move(3.,4.); printf("square.move(3.,4.);\n"); printf("square is at (%lf,%lf)\n",square.x_get(),square.y_get()); printf("\nEnd of testing\n"); return 0; } ] === Compile and Link === Linux [[code] dmd -c helloex.d dmd -c classCircle.d dmd -c classSquare.d dmd -c classShape.d g++ -c example_wrap.cxx g++ -c example.cxx g++ helloex.o -ohelloex classCircle.o classSquare.o classShape.o example_wrap.o example.o -lphobos -lpthread -lm ] The compilation is quite complicated. Each C++ file has to be compiled with g++, and each D file with dmd, and then all linked together with both the C++ and D libraries. This is the reason that I suggested FeatureRequestList/LinuxLinkOption. Windows The files have been copied unchanged from Linux. [[code] dmc -c example.cxx dmc -c example_wrap.cxx dmd helloex.d classCircle.d classSquare.d classShape.d example_wrap.obj example.obj ] === Output === [[code] hello world Testing interface to a C++ class Declare: Circle circle = new Circle(10.); circle has radius 10.000000 circle has perimeter 62.831853 circle has area 314.159265 Declare: Square square = new Square(10.); square has width 10.000000 square has perimeter 40.000000 square has area 100.000000 Testing inherited functions square is at (0.000000,0.000000) square.move(3.,4.); square is at (3.000000,4.000000) End of testing ] Note: this does not work with the original distribution by Andy Friesen. You will need my modifications to the files dmd.cxx and dmd.swg. JohnFletcher |
|
Wrap a C++ class
This example is adapted from the SWIG examples
Code to be wrapped
There are two files, the header file example.h and the function bodies example.cxx.
example.h
|
example.cxx
|
Interface file
The interface file for this is quite simple, as it just uses the header file for the class. This is the real key to work with SWIG and C++ code.
example.i
|
Run SWIG
|
Note the added parameter c++.
This generates the following files:
- example.d
- classCircle.d
- classSquare.d
- classShape.d
- examplePINVOKE.d
- example_wrap.cxx
Example Application
helloex.d
|
Compile and Link
Linux
|
The compilation is quite complicated. Each C++ file has to be compiled with g++, and each D file with dmd, and then all linked together with both the C++ and D libraries. This is the reason that I suggested FeatureRequestList/LinuxLinkOption.
Windows The files have been copied unchanged from Linux.
|
Output
|
Note: this does not work with the original distribution by Andy Friesen. You will need my modifications to the files dmd.cxx and dmd.swg.