Thursday, February 5, 2026

nanobind: the bridge between C++ and Python...

Python is where ideas move fast. C++ is where performance lives. For years, gluing the two together meant choosing between power, safety, and sanity. Enter nanobind—a modern, minimalist bridge that lets C++ and Python talk to each other cleanly, efficiently, and without ceremony.

nanobind is a C++17-first binding library, inspired by pybind11 but redesigned with a sharper focus on performance, compile times, and modern C++ practices. It’s built for developers who care about control—over lifetimes, memory, ABI stability, and error handling—without drowning in boilerplate.

What makes nanobind special is how unapologetically low-level it is, while still feeling elegant. It avoids heavy template metaprogramming where possible, compiles fast, and produces smaller binaries. If you’re working on large C++ codebases—CAD kernels, physics engines, solvers, graphics pipelines—this matters a lot.

Memory management is another strong point. nanobind gives you explicit control over object ownership between C++ and Python, making it ideal for systems where Python is embedded inside a C++ application (think Blender, FreeCAD, game engines, or simulation tools). You’re not just exporting functions—you’re designing an API boundary.

Compared to older tools like SWIG, nanobind doesn’t try to “auto-magically” generate bindings. That’s a feature, not a bug. You write bindings intentionally, so the Python API feels Pythonic, not like a leaked C++ header. And compared to pybind11, nanobind is leaner, stricter, and more future-facing.

In short:

  • Python for orchestration and scripting

  • C++ for performance-critical logic

  • nanobind as the clean, modern handshake between them

If you’re building serious software where Python is a first-class citizen—but not the performance bottleneck—nanobind is one of the best bridges you can choose today.

Here's my today's exploration on nanobind - the Factory pattern written in C++ being given a python interface using nanobind.

Enjoy...

The Factory Pattern written in C++.

/*

* 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_ */


/*

* 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 <nanobind/nanobind.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;

}



The bindings.cpp - defining the bridge...



#include <nanobind/nanobind.h>

#include <nanobind/stl/string.h> // Required for std::string support

#include "Factory.h"


namespace nb = nanobind;


// Use NB_MODULE to define the extension

NB_MODULE(foodfactory, m) {

// 1. Wrap the Base Class

// We use nb::class_<T> and provide the name it will have in Python

nb::class_<Food>(m, "Food")

.def("getName", &Food::getName);


// 2. Wrap the Subclasses

// Note: We specify the base class <Biscuit, Food> so Python knows the relationship

nb::class_<Biscuit, Food>(m, "Biscuit")

.def(nb::init<>());


nb::class_<Chocolate, Food>(m, "Chocolate")

.def(nb::init<>());


// 3. Wrap the Singleton Factory

nb::class_<Factory>(m, "Factory")

.def_static("get_instance", &Factory::getInstance, // Renamed to snake_case for Python idiomatic style

nb::rv_policy::reference)


.def("make_food", &Factory::makeFood, // Match your Python script's call

nb::rv_policy::take_ownership);}



And here is the CMakeLists.txt for compiling and creating the shared object


cmake_minimum_required(VERSION 3.15)

project(FactoryPattern_nanobind)


set(CMAKE_CXX_STANDARD 17)

set(CMAKE_CXX_STANDARD_REQUIRED ON)


# 1. Find Python

find_package(Python 3.9 COMPONENTS Interpreter Development REQUIRED)


# 2. Get nanobind paths manually to bypass the "Target Not Found" bug

execute_process(

COMMAND "${Python_EXECUTABLE}" -m nanobind --cmake_dir

OUTPUT_VARIABLE NB_DIR OUTPUT_STRIP_TRAILING_WHITESPACE

)

execute_process(

COMMAND "${Python_EXECUTABLE}" -m nanobind --include_dir

OUTPUT_VARIABLE NB_INC OUTPUT_STRIP_TRAILING_WHITESPACE

)


# 3. Load the nanobind logic

list(APPEND CMAKE_PREFIX_PATH "${NB_DIR}")

find_package(nanobind REQUIRED CONFIG)


# 4. Create the module

nanobind_add_module(foodfactory

LTO

Biscuit.cpp

Chocolate.cpp

Factory.cpp

bindings.cpp

)


# 5. MANUALLY fix the missing target link

# This bypasses the error by providing the includes and libraries directly

target_include_directories(foodfactory PRIVATE "${NB_INC}" "${Python_INCLUDE_DIRS}")

target_link_libraries(foodfactory PRIVATE Python::Module)


# If nanobind still complains about the target, we define it as an alias

if(NOT TARGET nanobind::nanobind)

add_library(nanobind::nanobind INTERFACE IMPORTED)

set_target_properties(nanobind::nanobind PROPERTIES

INTERFACE_INCLUDE_DIRECTORIES "${NB_INC}"

)

endif()


After compiling and creating the shared object, you need to put it

inside the Python project and import it.


The Python code looks as follows.


import foodfactory
# Access get_instance THROUGH the Factory class
factory = foodfactory.Factory.get_instance()
biscuit = factory.make_food("bi")
print(biscuit.getName())
chocolate = factory.make_food("ch")
print(chocolate.getName())

And here are my earlier explorations on C++-Python bridge like pybind11, Boost.Python, SWIG, etc.

Enjoy 


Friday, January 30, 2026

It's neither strength nor intelligence but resilience creates champs - a timeline of Bharat from 2014 to 2026...



2014 | The Psychological Reset

This wasn’t about policy first — it was about mindset.

  • “Make in India” reframes manufacturing as strategic, not menial
  • Space, defence, digital get political backing
  • Bureaucracy is told: delay is more dangerous than failure

Shift: From risk-avoidance to attempting scale


2015 | Digital Foundations

  • Jan Dhan–Aadhaar–Mobile (JAM) stack stabilizes
  • India begins building public digital rails instead of private monopolies
  • Direct Benefit Transfer reduces leakages massively

Shift: Infrastructure > schemes


2016 | Shock as Discipline

  • Demonetisation causes pain, but forces digitisation
  • UPI launches quietly — underestimated, underreported
  • Cyber, fintech, digital identity ecosystems accelerate

Shift: Informality → traceability


2017 | Systems Thinking Emerges

  • GST implemented — messy, painful, but irreversible
  • ISRO cryogenic engine reliability improves
  • Tejas edges toward operational clearance

Shift: One market, one system


2018 | Strategic Patience

  • Defence procurement rules rewritten
  • Indigenous content prioritised
  • AI, robotics, and data policy discussions begin

Criticism continues, but direction is set.

Shift: Policy lag accepted in exchange for autonomy


2019 | Quiet Capability

  • Mission Shakti (ASAT) proves space deterrence
  • Chandrayaan-2 attempts high-risk landing
  • Semiconductor vulnerability officially acknowledged

Shift: Signalling without chest-thumping


2020 | Crisis as Accelerator

COVID stress-tests everything.

  • Digital infrastructure holds
  • Vaccine manufacturing scales at unprecedented speed
  • Supply chain nationalism becomes global reality

Shift: Resilience becomes measurable


2021 | From Slogan to Structure

  • Atmanirbhar Bharat policies deepen
  • PLI schemes target electronics, pharma, defence
  • API and chip dependencies mapped sector-by-sector

Shift: Strategic self-reliance, not isolation


2022 | Manufacturing Re-enters the Room

  • Mobile phone manufacturing explodes
  • Defence exports cross psychological thresholds
  • Semiconductor Mission formally launched

Shift: Assembly → ecosystem thinking


2023 | Validation Moment

  • Chandrayaan-3 lands near lunar south pole
  • Global admiration for Indian engineering discipline
  • UPI exported diplomatically
  • AI compute access discussed as national infrastructure

Shift: Confidence without explanation


2024 | Hard Tech Focus

  • GaN, compound semiconductors prioritized
  • AIRAWAT & iKosha scale sovereign compute
  • GPU access democratized for researchers
  • Sanskrit, Indian language AI pipelines emerge

Shift: From users of tech → builders of tech


2025 | Strategic Convergence

  • Defence, space, AI, semiconductors align
  • Dual-use technologies openly encouraged
  • Export control resilience improves
  • Indigenous IP creation accelerates

Shift: Civil + military tech convergence


2026 | The New Normal

By now, a pattern is undeniable:

  • Indigenous systems are the default
  • Failure is tolerated if learning is visible
  • Long-term national missions outlive political cycles

Bharat is no longer “catching up”.

It is choosing what to build, what to ignore, and what to defend.


The Core Insight

2014–2026 wasn’t about sudden brilliance.
It was about staying in the game long enough.

It was the story of the transformation of a caged lion into a roaring lion.

Strength intimidates.
Intelligence impresses.
Resilience wins championships.
 

Tuesday, December 30, 2025

Lesson from Russia Ukraine war - why Starlink possess a threat to national security because hundreds of Leo satellites may operate drones during war time...

The Russia-Ukraine war has fundamentally rewritten the rules of modern warfare, specifically through the "democratization" of satellite communications. While Starlink was initially hailed as a lifeline for Ukraine, it has evolved into a complex national security threat for several reasons.

The core of the threat lies in the fact that Low Earth Orbit (LEO) constellations like Starlink provide the high-bandwidth, low-latency connectivity required to operate sophisticated drones over vast distances—capabilities once reserved for superpower militaries.

1. Enabling Long-Range "Kill Webs"

Traditionally, drones were limited by line-of-sight radio links or expensive, laggy geostationary satellites. Starlink’s LEO satellites (hundreds of which are overhead at any given time) allow for:

Beyond Line of Sight (BLOS) Control: 

Operators can sit hundreds of miles away from the front lines and control FPV (First Person View) or strike drones via the satellite link.

Real-time Video Feedback: 

The low latency (under 50ms) allows for precise, real-time maneuvering of "kamikaze" drones, making them as accurate as guided missiles but at a fraction of the cost.

Autonomous Swarming: 

Thousands of satellites enable the coordination of drone "swarms," where multiple units communicate and strike simultaneously without relying on vulnerable ground-based towers.

2. The "Dual-Use" Dilemma & Adversary Adaptation

The war has proven that commercial technology is difficult to "gatekeep."

Russian Integration: 

Recent reports indicate Russian forces have begun integrating Starlink terminals directly into their own strike drones (e.g., the Molniya-2). By using black-market terminals, Russia can bypass its own lack of high-speed satellite infrastructure.

The Geofencing Problem: 

It is extremely difficult for SpaceX to disable Starlink for Russians without also disabling it for Ukrainians in contested "grey zones." This creates a scenario where a private company effectively dictates the "digital borders" of a war.

3. Resilience Against Electronic Warfare (EW)

LEO constellations are inherently harder to jam than traditional systems:

Narrow Beams: 

Starlink uses phased-array antennas that create very narrow, directed beams.7 To jam it, an enemy must be almost directly between the dish and the satellite.

Redundancy: 

Because there are thousands of satellites, if one is jammed or destroyed, the terminal simply "handshakes" with the next one in the mesh network. This makes "denial of service" nearly impossible through conventional means.

4. Sovereignty and the "Private Actor" Risk

A major national security concern is that a nation's military effectiveness now depends on a private corporation’s terms of service.

Unilateral Veto Power: 

We saw this when Elon Musk reportedly denied a request to activate Starlink near Crimea for a Ukrainian naval drone strike. This highlights a "threat" where a private individual can interfere with a nation's strategic military objectives based on personal or political views.

LEO Satellites vs. Traditional Military Comms

FeatureTraditional Military Satellite (GEO)Starlink LEO Constellation
LatencyHigh (600ms+); bad for drone pilotingLow (<50ms); enables real-time piloting
VisibilitySingle point of failure; easy to targetThousands of nodes; nearly impossible to "kill"
AccessibilityRestricted to high-budget militariesAvailable to anyone with $500 and a subscription
MobilityRequires large, static dishesPortable; can be strapped to the roof of a car or drone

Bottom Line:


The threat isn't just that the satellites "operate" the drones, but that they provide a ubiquitous, un-jammable internet layer that turns any cheap civilian drone into a precision-guided strategic weapon.