Do you want to know how to create and C++ functions in a Python app? In this article we will show you how to use the new C++ Builder 12 to create a C++ function, step by step, and then call that function in any Python app. C++ Builder 12 is released packed full of great features, optimizations, and improvements. One of the great features of C++ Builder 12 was the inclusion of an initial CLANG C++ compiler which is another big step introducing a new 64bit bcc64x CLANG compiler which supports C++11, C++14, C++17, and partially C++20 standards. It is still in active development, but I would like to explain there is a great feature of new clang compiler that supports the latest Python modules. In this post, we explain how to develop Python modules with the new bcc64x C++ Builder 12 CLANG compiler.
Table of Contents
What about using Python with Delphi?
If you are using Delphi, you should also check out the Python4Delphi tools.
You can find out more about our free Python tools here.
and read about Python4Delphi in this blog post:
What is Python?
Python is hugely popular and has some really useful libraries. Python is particularly strong in the field of AI and machine learning (ML). If you are C++ developer, you might want your users to be able to analyze data with AI modules or frameworks written in the Python language in your applications. Let’s imagine you want the users to carry out a few button-clicks to do some heavy AI analysis. That way you get the best of both worlds by having the raw speed and power of C++ which can run Python modules.
In the programming world today, the Python programming language is very popular – perhaps second only to C++. Python is easy to use, and hugely popular because it is easy to learn and has the support from big companies like Google. One of the areas in which Python is particularly successful are with libraries and frameworks for AI technology and machine learning. It is a great object-oriented, interpreted, and interactive programming language. Python has very clear syntax. It has modules, classes, exceptions, very high-level dynamic data types, and dynamic typing. There are interfaces to many system calls and libraries, as well as to various windowing systems. New built-in Python modules are easily written in C or C++. Python is also usable as a scripting extension for applications written in other languages that benefit from its ease of use. Python is free to use. More information can be found on their official web page https://www.python.org/
The latest version of Python (at the time of writing) is Python 3.12, released in October 2023. It has a lot of new changes and improvements; you can download it from here: https://www.python.org/downloads/
What is the new C++ Builder 12 and its new CLANG Compiler?
Do you know, you can develop Python modules with the new bcc64x compiler in a C++ Builder 12? Yes, the new bcc64x is compatible with the latest version of Python. I should note that, this compiler is not integrated into IDE yet (it is planned, soon) but nervertheless we can use RAD Studio Command Prompt for the C++ Builder 12.
Here are some great features of C++ Builder 12,
- Comes with a special CLANG 15 Win64 compiler
– Win64 is a primary OS
– New Clang means support for C++20 and a lot of C++23 features
– Important to have more compatible standards and amazingly faster
– In memory allocation operations, it is 6 to 14% faster than the current CLANG Win64 compiler in C++ Builder
– In unordered map hashing, STL performance is 60 to 70% faster than the current CLANG Win64, and 40 to 70% faster than the current CLANG Win32 in C++ Builder - Comes with a new Visual Assist in the IDE
– Fast code completion
– Navigation and refactoring
– and many useful developer tools - Debugging will use PDB outputs within the IDE
- VCL and FMX have not adopted yet, this may take time
- This presentation is an early preview, unfiltered and incomplete, they do not promise these features to be in 12.0
How to write a Python module in C++?
The official Python page explains how you can extend Python by adding new built-in modules https://docs.python.org/3/extending/extending.html . Let’s sum up all here below.
First, let’s create our simple Hello World module in C++, this file will be “hello.cpp“. Create a new cpp file with RAD Studio or with any IDE. Now, let’s develop our first Python module in C++.
1. Include Python.h header
Include your headers and then include Python header,
1 2 3 |
#include <Python.h> |
Be sure that path folder of python header files is defined in your compiler options.
2. Define your function
Let’s define a world() function that prints “Hello C++ World!”,
1 2 3 4 5 6 7 8 |
int world() { // NOTE You must change the forward slash in the line below after "World" to a backslash printf("Hello C++ World/n"); return 0; } |
3. Create a Python object for your function and return to Python
1 2 3 4 5 6 |
static PyObject* world(PyObject* self, PyObject* args) { return Py_BuildValue("s", world()); } |
4. Store all your functions above by creating array of static type PyMethodDef
1 2 3 4 5 6 7 8 |
static PyMethodDef hello_methods[] = { // { "function_name", role , METH_VARARGS, arguments } {"world", world, METH_VARARGS, "Print Hello World."}, {NULL, NULL, 0, NULL} // End of the list of methods }; |
5. Create the structure with the name of the module to be used in Python,
1 2 3 4 5 6 7 8 9 10 |
static struct PyModuleDef hello_module = { PyModuleDef_HEAD_INIT, // Informs the base "hello", // The name of your library NULL, // The name of the documentation -1, // The module size, -1 is the maximum size hello_methods // The module name with underscore and methods at the end }; |
6. Create a gateway to Python. The return type must be: PyMODINIT_FUNC
,
The name must be PyInit
_ the name of your lib (void arguments), i.e. for the hello library it must be PyInit_hello(void)
.
1 2 3 4 5 6 |
PyMODINIT_FUNC PyInit_hello(void) { return PyModule_Create(&hello_module); // Return PyModule_Create and pointer & the PyModuleDef struct } |
As a result, we will have hello.cpp
file. We will compile and use this file in steps below.
How to develop Python modules with the new C++ Builder 12 CLANG compiler?
Step 1. Generate Python import library
Goto Python installation directory and generate the import library from Python dll
1 2 3 |
mkexp python312.a python312.dll |
Step 2. Copy Python import library
Copy the python312.a into the Python libs folder (i.e. “PythonPython312libs”)
Step 3. Create your C++ code for the Python module
Create hello.cpp
file to develop a “Hello World” example as described above. Here is the full C++ code example:
hello.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
// Include Python header #include <Python.h> // Define your function int world() { // NOTEL You must change the forward slash after the word "World" in the line below to a backslash printf("Hello C++ World/n"); return 0; } // Create Python object for your function in arguments and return to Python static PyObject* world(PyObject* self, PyObject* args) { return Py_BuildValue("s", world()); } // Store all your functions above by creating array of static type PyMethodDef static PyMethodDef hello_methods[] = { // { "function_name", role , METH_VARARGS, arguments } {"world", world, METH_VARARGS, "Print Hello World."}, {NULL, NULL, 0, NULL} // End of the list of methods }; // Create the structure with the name of the module to be used in Python static struct PyModuleDef hello_module = { PyModuleDef_HEAD_INIT, // Informs the base "hello", // The library name NULL, // The documentation name -1, // The module size, -1 is the maximum size hello_methods // The module name with underscore and methods at the end }; // Create a gateway to Python, return type must be: PyMODINIT_FUNC // The function name should be PyInit_ the name of your lib (void arguments) PyMODINIT_FUNC PyInit_hello(void) { return PyModule_Create(&hello_module); // Create Py module and return pointer at the PyModuleDef struct } |
Step 4. Create some Python code that uses the module
In Python, we use modules by using import
command. Then we can run our world()
method of the hello
library. Create a new test.py
python code as shown below.
test.py
1 2 3 4 5 |
import hello hello.world() |
Step 5. Create a bat file that creates a shared library using bcc64x
If you want to compile a Python module in C++ with bcc64x the best way is creating a .bat file that has compiler options. Of course, you can do this in a single line command. In this example we will use .bat file.
To compile hello.cpp with the new bcc64x compiler, in addition to bcc64x command,
- we need to define other options (%OPTS%), library paths (%LIBS%), include paths (%INCS%)
- we should use python312 import library by using -lpython312 parameter
- we should compile hello.cpp file by using .hello.cpp source module file in C++
- we should use -shared and -undefined dynamic_lookup options
Create a new compile.bat
file with a notepad or with any IDE . Here is an example compile.bat file that shows how to compile C++ file (.cpp) as a shared library module (.pyd). Note that you should modify this code below with your own user folder name and settings (here mine was atavm
)
compile.bat
Note that due to a limitation of the blogging platform you should replace the forward slashes in the paths with backslashes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
setlocal set OPTS=-D_CRT_SECURE_NO_WARNINGS^ -D_USE_MATH_DEFINES^ -DWIN32^ -D_DEBUG^ -D_WINDOWS set LIBS=-L"C:/Users/yilmaz/AppData/Local/Programs/Python/Python312/libs" set INCS=-I"C:/Users/yilmaz/AppData/Local/Programs/Python/Python312/include" bcc64x.exe %OPTS% %LIBS% %INCS% -lpython312 .hello.cpp -shared -undefined dynamic_lookup -o hello.pyd |
This will create a shared library module using bcc64x, be sure that the LIBS
and INCS
folder are correct, and your file names are correct. When you run this bat file in PowerShell or DOS, this will create hello.pyd
Python module by using python312
import library and by compiling hello.cpp
file as in the options above.
Step 6. Execute compile.bat and run Python example
On the PowerShell or DOS prompt, execute compile.bat and run test.py example as below.
1 2 3 4 |
> compile.bat > python .test.py |
and the output will be as follows:
1 2 3 |
Hello C++ World! |
C++ Builder is the easiest and fastest C and C++ compiler and IDE for building simple or professional applications on the Windows operating system. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for UIs.
There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition