Exposing a C++ API to Python

I'm currently working on a project were I had to wrap the C++ classes with Python to be able to script the program. So my specific experience also involved embedding the Python interpreter in our program.

The alternatives I tried were:

  • Boost.Python

    I liked the cleaner API produced by Boost.Python, but the fact that it would have required that users install an additional dependency made us switch to SWIG.

  • SWIG

    SWIG's main advantage for us was that it doesn't require end users to install it to use the final program.

What have you used to do this, and what has been your experience with it?

Asked by: Kimberly251 | Posted: 28-01-2022

Answer 1

I've used both (for the same project): Boost is better integrated with the STL, and especially C++ exceptions. Also, its memory management mechanism (which tries to bridge C++ memory management and Python GC) is way more flexible than SWIG's. However, SWIG has much better documentation, no external dependencies, and if you get the library wrapped in SWIG for Python you're more than half-way there to getting a Java/Perl/Ruby wrapper as well.

I don't think there's a clear-cut choice: for smaller projects, I'd go with Boost.Python again, for larger long-lived projects, the extra investment in SWIG is worth it.

Answered by: Dainton382 | Posted: 01-03-2022

Answer 2

EDIT - the Robin project is sadly abandoned, and won't be much use today

I've used Robin with great success.

Great integration with C++ types, and creates a single .cpp file to compile and include in your shared object.

Answered by: Rafael661 | Posted: 01-03-2022

Answer 3

I suggest SIP. SIP is better than SWIG due to the following reasons:

  1. For a given set of files, swig generates more duplicate (overhead) code than SIP. SIP manages to generate less duplicate (overhead) code by using a library file which can be statically or dynamically linked. In other words SIP has better scalability.

  2. Execution time of SIP is much less than that of SWIG. Refer Python Wrapper Tools: A Performance Study. Unfortunately link appears broken. I have a personal copy which can be shared on request.

Answered by: David184 | Posted: 01-03-2022

Answer 4

pyrex or cython are also good and easy ways for mixing the two worlds.

Wrapping C++ using these tools is a bit trickier then wrapping C but it can be done. Here is the wiki page about it.

Answered by: Daryl581 | Posted: 01-03-2022

Answer 5

A big plus for Boost::Python is that it allows for tab completion in the ipython shell: You import a C++ class, exposed by Boost directly, or you subclass it, and from then on, it really behaves like a pure Python class.

The downside: It takes so long to install and use Boost that all the Tab-completion time-saving won't ever amortize ;-(

So I prefer Swig: No bells and whistles, but works reliably after a short introductory example.

Answered by: Melissa535 | Posted: 01-03-2022

Similar questions

python - exposing boost uuid with SWIG

I have my existing working code that depends on boost::uuids::uuid. Now I an trying to generate a python module out of it. SWIG is successfully generating all important classes and functions. But I am facing problem with the functions that takes or returns boost uuid. I want to convert between boost uuid and python uuid. Is there any uuid.i that I can use ? I see there is an uuid python module.I under...

python - Exposing ML model output to rest api

I have a sample model which takes below features [ data['ApplicantIncome'], data['CoapplicantIncome'], data['LoanAmount'], data['Loan_Amount_Term'], data['Credit_History'], data['gender_Female'], data['marriage_Yes'], data['education_Graduate'], data['employed_Yes'], data['property_Rural'], data['property_Semiurban'], data['property_Urban'] ]

Error in exposing C++ Enum Class to Python Code

I have to expose a C++ enum class into python. I have checked some examples but all are about C-style enum type. However, I need to use enum class. Any suggestion? Here is my code: zoo.h namespace extzoo { namespace intzoo { class zoo { public: enum class Size { small, medium, large }; const std::string hello_zoo(); const std::str...

python - Django in Docker without exposing to LAN

When running Django in a container, I am unable to access it unless running with python manage.py runserver However, doing so allows anyone on my network to connect, which I do not want. In my docker compose file, I have: ports: - "8000:8000" When accessing by just running python manage.py runserver, I get an...

exposing c++ class to python

Forgive me, I'm an engineer tasked with programming. I'm not a programmer. I am somewhat familiar with python. My goal is to get this radio working using a raspberry pi 3, but all of the radio's code is written in c++. I need to expose these c++ classes to python, and I'm making progress but I'm stuck. In this class, There is a function to turn the radio on (SX1272::ON()) and in this function, it calls the setMaxCurren...

c++ - How can I embed python in c ++ without exposing the my source code

I would like to embedding python program from my c++ program. I looking for Boost python, pypind, C/P...

Exposing Python class to Rust

I'm trying to do a simple task of handling a Python class in Rust. Instantiate it, do an operation and than access one of its members. I extensively looked at PyO3 and cpython documentation and they cover a lot of the opposite (calling Rust from Python). Why in the code below the application cannot find the attributes? Python side: class Vehicle: def __i...

oop - Exposing members or make them private in Python?

Is there a general convention about exposing members in Python classes? I know that this is a case of "it depends", but maybe there is a rule of thumb. Private member: class Node: def __init__(self): self.__children = [] def add_children(self, *args): self.__children += args node = Node() node.add_children("one", "two") Public member: class Node2: ...

python - Django: Exposing model method to admin

Example model: class Contestant(models.Model): first_name = models.CharField(max_length=255) last_name = models.CharField(max_length=255) email = models.EmailField() ... def send_registration_email(self): ... I'd like to be able to expose this method to the admin so that managers can login and manually call it. I'm thinking about trying property attributes but...

api - Exposing a C string without copying to python 3.x code

I have a library written with cython that wraps a C library, and i'm exposing a few c strings into python code. Those strings are large, and static (can't deallocate them) so just making a python string from them (that makes a copy) is not an option - i get OOM errors. I have the code working for python 2.x currently using the old buffer API, which looks more or less like: def get_foo(): retur...

Exposing C++ library to Python + PIL

I started using SWIG on a huge C++ library (made of of several inter-dependent static libs) to expose it to python. This library defines many primitive classes that are used throughout as parameters (images of different types for example). There is extensive use of STL, inheritance and templating in the lib as well. So far I have a minimal portion of the lib usable from Python but would like to progressively add th...

python - Exposing model method with Tastypie

I am currently working on implementing an API into my Django project and Tastypie seemed like it would be most suitable. What I can't seem to work out is how to expose a function within my model using Tastypie. For example, I have this model: class game(models.Model): id = models.AutoField("ID", primary_key=True, editable=False) ip_address = models.OneToOneField(IPAddress, verbose_na...

c++ - boost exposing classes LNK2019 / module does not define init function

I know those errors in the headline are nothing new, but in this constellation I have here it's rather strange and I don't find a solution that is helping. So let me explain. I'm working with boost.python, Visual Studio 2012 and the tutorial from the developers site. So as i finally fixed all linker problems and imports I got the first tutorial working: char const* greet() { return "hello, world"...

python - Run web server locally without exposing it publicly?

This question already has answers here:

how to use Python to send email without exposing password?

This snippet works but the password in the code is wide open: import smtplib server = smtplib.SMTP('smtp.gmail.com', 587) server.ehlo() server.starttls() server.ehlo() server.login("usrname", "pw") msg = "\nHello!" # The /n separates the message from the headers server.sendmail("me@gmail.com", "u@gmail.com", msg) server.quit() I'm wondering how to do this securely. edit: ...

Exposing Qt C++ QObject to Python

I have a software component (Qt/C++ GUI-less library) that performs some data-intensive manipulation. What is the best way to expose it's functionality as a Python native extension? Wrapping it by hand in Boost::Python? Anything QObject/QMetaObject based instead? Perhaps reusing QScript wrappers? Note - I know this question borders on the soft-rec, but I presume there might be a canonical way to do it...

c++ - Exposing STL structs in Python w/o memory leak

I have a std::vector<CameraT> which I've already bound to Python thanks to Flexo's response for SWIG and C++ memory leak with vector of pointers. But I need to access fields like CameraT.t and I can't find a proper way to do it. It is defined in a 3rd party header file (DataInterfac...

Still can't find your answer? Check out these communities...

PySlackers | Full Stack Python | NHS Python | Pythonist Cafe | Hacker Earth | Discord Python