DEV Community

Somenath Mukhopadhyay
Somenath Mukhopadhyay

Posted on

Do you want your python code to access C/C++ code? use SWIG...

SWIG (Simplifies Wrapper and Interface Generator) is an interface compiler that connects programs written in C and C++ with scripting languages such as Perl, Python, Ruby, and Tcl. It works by taking the declarations found in C/C++ header files and using them to generate the wrapper code that scripting languages need to access the underlying C/C++ code.

Using SWIG, you can replace the main() function of a C/C++ program with a scripting interpreter from which you can control the application. This adds quite a lot of flexibility and makes the program "programmable."

SWIG allows C/C++ programs to be placed in a scripting environment that can be used for testing and debugging. For example, you might test a library with a collection of scripts or use the scripting interpreter as an interactive debugger.

With SWIG, different C/C++ programs can be turned into scripting language extension modules. These modules can then be combined together to create new and interesting applications.

SWIG is sometimes compared to interface definition language (IDL) compilers such as those you find with systems such as CORBA and COM. Although there are a few similarities, the whole point of SWIG is to make it so you don't have to add an extra layer of IDL specifications to your application.

SWIG requires little, if any, modifications to existing code. For the most part, it encourages you to keep a clean separation between C/C++ and its scripting interface.

The primary audience of SWIG is C/C++ programmers who want to add a scripting language component to their applications.

So... here we go...

My experimentation with SWIG...
I have made a Python interface for my existing Factory Pattern project written in C++. Here's the C++ code of the Factory Pattern.

/*
 * Food.h
 *
 *  Created on: Mar 10, 2021
 *      Author: som
 */

#ifndef FOOD_H_
#define FOOD_H_
#include <string>

using namespace std;

class Food {
public:
    virtual string getName() = 0;

    virtual ~Food(){

    }
};


#endif /* FOOD_H_ */
Enter fullscreen mode Exit fullscreen mode
/*
 * Biscuit.h
 *
 *  Created on: Mar 10, 2021
 *      Author: som
 */

#ifndef BISCUIT_H_
#define BISCUIT_H_

#include "Food.h"

class Biscuit: public Food {
public:
    Biscuit();
    string getName();
    ~Biscuit();
};

#endif /* BISCUIT_H_ */

/*
 * Biscuit.cpp
 *
 *  Created on: Mar 10, 2021
 *      Author: som
 */
#include <iostream>
#include "Biscuit.h"
using namespace std;


Biscuit::Biscuit() {
    // TODO Auto-generated constructor stub
    cout<<"Biscuit is made..."<<endl;

}

Biscuit::~Biscuit(){}


string Biscuit::getName(){
    return "It's a Biscuit";
}

/*
 * Chocolate.h
 *
 *  Created on: Mar 10, 2021
 *      Author: som
 */

#ifndef CHOCOLATE_H_
#define CHOCOLATE_H_

#include <iostream>
#include "Food.h"

class Chocolate: public Food {
public:
    Chocolate();
    virtual ~Chocolate();
    string getName();
};


#endif /* CHOCOLATE_H_ */

/*
 * Chocolate.cpp
 *
 *  Created on: Mar 10, 2021
 *      Author: som
 */

#include "Chocolate.h"


Chocolate::Chocolate() {
    // TODO Auto-generated constructor stub
    cout<<"Chocolate is made..."<<endl;

}

Chocolate::~Chocolate() {
    // TODO Auto-generated destructor stub
}

string Chocolate::getName(){
    return "It's a Chocolate";
}

/*
 * Factory.h
 *
 *  Created on: Mar 10, 2021
 *      Author: som
 */

#ifndef FACTORY_H_
#define FACTORY_H_


#include <iostream>
#include <string>

#include "Biscuit.h"
#include "Chocolate.h"

using namespace std;

class Factory{
public:
    static Factory* instance;
    static Factory* getInstance();

    Food* makeFood(const string& type);

private:
    Factory(){}

    // Delete copy constructor & assignment operator (Singleton pattern)
    Factory(const Factory&) = delete;
    Factory& operator=(const Factory&) = delete;
};
//Factory* Factory:: instance =  NULL;


#endif /* FACTORY_H_ */

/*
 * Factory.cpp
 *
 *  Created on: Jan 30, 2025
 *      Author: som
 */
#include "Factory.h"
Factory* Factory::instance = NULL;

Factory* Factory:: getInstance(){
        if(Factory::instance == NULL){
            Factory::instance = new Factory();
        }
        return Factory::instance;
    }

Food* Factory::makeFood(const string& type){
        if(type.compare("bi") == 0){
            return new Biscuit();
        }
        if(type.compare("ch") == 0){
            return new Chocolate();
        }

        return NULL;
    }

Enter fullscreen mode Exit fullscreen mode
Step II : Define the interface (.i) file FactoryPatternSwig.i
%module FactoryPatternSwig
%{
#include "Factory.h"
%}
%include "std_string.i"
%include "Food.h"
%include "Biscuit.h"
%include "Chocolate.h"
%include "Factory.h"
Enter fullscreen mode Exit fullscreen mode

Step III :
Run the command

swig -c++ -python FactoryPatternSwig.i
Enter fullscreen mode Exit fullscreen mode

It will generate

FactoryPatternSwig.py and FactoryPatternSwig_wrap

Step IV :
Compile the Wrapper by running the following command...

g++ -fPIC -c Biscuit.cpp Chocolate.cpp Factory.cpp FactoryPatternSwig_wrap.cxx -I/usr/include/python3.8
Enter fullscreen mode Exit fullscreen mode

and

 g++ -shared -o _FactoryPatternSwig.so Biscuit.o Chocolate.o Factory.o FactoryPatternSwig_wrap.o
Enter fullscreen mode Exit fullscreen mode

This will generate the _FactoryPatternSwig.so

shared object.

Once compiled, you can copy the _FactoryPatternSwig.so and put it inside a Python project. Don't forget to keep the FactoryPatternSwig.py file in the python workspace.

Now we can use this shared library as I have done in the python workspace...

import FactoryPatternSwig

factory = FactoryPatternSwig.Factory.getInstance()

biscuit = factory.makeFood("bi")
print(biscuit.getName())  # Expected: "Biscuit"

chocolate = factory.makeFood("ch")
print(chocolate.getName())  # Expected: "Chocolate"
Enter fullscreen mode Exit fullscreen mode

And.... that's it.

U will get the result on the Python console.

Enjoy...

AWS GenAI LIVE image

How is generative AI increasing efficiency?

Join AWS GenAI LIVE! to find out how gen AI is reshaping productivity, streamlining processes, and driving innovation.

Learn more

Top comments (0)

Billboard image

Create up to 10 Postgres Databases on Neon's free plan.

If you're starting a new project, Neon has got your databases covered. No credit cards. No trials. No getting in your way.

Try Neon for Free →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay