Last update October 21, 2004

Dwith Swig / Examples /
Pragma



Table of contents of this page
C++ classes with pragma   
Code to be wrapped   
Interface File   
Run SWIG   
Example Application   
Compile and Link   
Output   

C++ classes with pragma    

This example has been constructed to illustrate the solution which I have developed to solve the /Problem. The example has a C++ header file defining two classes A and B. In the application B has a member A. As SWIG puts the D code into two separate files, the code for class B needs access to the definition of class A. This is achieved using an import statement in the D code. The insertion of extra code is handled using a pragma command within the SWIG interface file.

Code to be wrapped    

example.h

// example.h for dmd pragma example

class A {
  int a;
 public:
  A(int aa): a(aa) { }
  int getA() const { return a; }
  void setA(int aa ) { a = aa; }
};

class B {
  A a;
 public:
  B(int aa): a(aa) { }
  A getA() const { return a; }
  int getB() const { return a.getA(); }
  void setB(int b) { a.setA(b); }
};

Interface File    

example.i

/* File : example.i */
%module example

/* This example illustrates what I have called problem (2) on the wiki4d.
 *
 * I have made two small classes called A and B.
 *
 * B needs the definition of A, which is added to the shadow D class
 * using the %pragma(dmd) command.
 *
 * John Fletcher  (J.P.Fletcher@aston.ac.uk) (c) 2004.
 */

%{
#include "example.h"
%}

class A {
  int a;
 public:
  A(int aa): a(aa) { }
  int getA() const;
  void setA(int aa ) { a = aa; }
};

// Protection so that it is only seen when using dmd.
#ifdef SWIGDMD
%pragma(dmd) classimports="private import classA;"
#endif

class B {
  A a;
 public:
  B(int aa) : a(aa) { }
  A getA() const { return a; }
  int getB() const { return a.getA(); }
  void setB(int b) { A.setA(b); }
};

  • This gives an example of use of the pragma command to define the import statement to be added. Each pragma command remains in force until another with the same name is given. This can be used to control different insertions into several classes.
  • It also gives an example of the use of a predefined constant SWIGDMD which can be use to control different actions to be taken when wrapping for different target languages. See /MoreAboutSwig .
  • Note also that in this case the class definition for D is not taken directly from the C++ header file.

Run SWIG    

swig -dmd -c++ example.i

In this case the command echoes the output from the processing of the pragma statement:

classimports = private import classA;

The output is the following files

  • example.d which is empty
  • classA.d
  • classB.d
  • examplePINVOKE.d
  • example_wrap.cxx

Example Application    

runex.d

/* runex.d testing example.i interface */

import std.string;

private import classB;
private import classA;

int main(char[][] args)
{
   printf("Test of example with two classes\n\n");

   A a = new A(1);
   printf("a.getA() = %d\n",a.getA());
   B b = new B(2);
   printf("b.getB() = %d\n",b.getB());
   A ab;
   ab = b.getA();
   printf("ab.getA() = %d\n",ab.getA());

   printf("\nEnd of testing\n");
   return 0;
}

Compile and Link    

Linux

dmd -c runex.d
dmd -c classA.d
dmd -c classB.d
g++ -c example_wrap.cxx
g++ runex.o -orunex classA.o classB.o example_wrap.o -lphobos -lpthread -lm

Note that this case has no seperate C++ file of function bodies.

Windows to follow.

Output    

Test of example with two classes

a.getA() = 1
b.getB() = 2
ab.getA() = 2

End of testing


FrontPage | News | TestPage | MessageBoard | Search | Contributors | Folders | Index | Help | Preferences | Edit

Edit text of this page (date of last change: October 21, 2004 12:16 (diff))