Friday, October 11, 2024

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...

Step I. MyClass.h

#ifndef MYCLASS_H
#define MYCLASS_H

class MyClass {
public:
    MyClass();
    ~MyClass();
    void set_value(int val);
    int get_value() const;

private:
    int value;
};

#endif

Step II

MyClass.cpp

#include "MyClass.h"

MyClass::MyClass() : value(0) {}

MyClass::~MyClass() {}

void MyClass::set_value(int val) {
    value = val;
}

int MyClass::get_value() const {
    return value;
}


Step III


MyClass.i - the SWIG interface file...


%module MyClass
%{
#include "MyClass.h"
%}

%include "MyClass.h"


Step IV


Generate the Wrapper Code Using SWIG


Run in terminal the following command


swig -python -c++ MyClass.i


This generates two files:

  • MyClass_wrap.cxx: The C++ wrapper code SWIG generates.
  • MyClass.py: The Python module that SWIG creates, which interfaces with the C++ code.

Step V

Then compile the C++ code and the SWIG-generated wrapper using g++ or another compiler. Make sure to link against Python libraries as shown below


g++ -fPIC -shared MyClass_wrap.cxx MyClass.cpp -I/usr/include/python3.x -o _MyClass.so


Here:

  • -fPIC ensures that the code is position-independent (required for shared libraries).
  • -shared tells the compiler to generate a shared library (_MyClass.so).
  • The -I flag specifies the path to Python headers.

Step VI

Once compiled, you can use the MyClass module in Python:

import MyClass

# Create an instance of MyClass
obj = MyClass.MyClass()

# Set and get value using the wrapped C++ methods
obj.set_value(100)
print(obj.get_value())  # Output: 100


No comments: