Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Python

C/C++ – Python interop

3.00/5 (1 vote)
13 Dec 2011CPOL2 min read 20.2K  
Python interop in C/C++.

Making Python work with C/C++ can be achieved in a couple of ways, either writing a DLL with a Python API, or using the ctypes library module.

When working with Python, it is useful to have virtual environments so that we have a clean and isolated Python environment. Although it is not necessary for this example, I’ll run through the steps necessary:

Then:

c:\> cd c:\python27\scripts
c:\python27\scripts> easy_install virtualenv
c:\python27\scripts> easy_install pip

and then:

C:\Python27\Scripts>virtualenv --distribute --prompt=(myenv) %USERPROFILE%\myenv

New python executable in C:\Users\user\myenv\Scripts\python.exe
Installing distribute...........................................................
................................................................................
....................................................done.
Installing pip.................done.

Then enter your virtualenv

c:\> C:\Users\user\myenv\Scripts\activate.bat
(myenv) c:\>

where you can now use pip install to download and install python modules into the virtualenv as necessary.

If you want to use the Python Tools for Visual Studio, ensure that you change %USERPROFILE% to $(UserProfile) in the (Python) project settings so that you run Python from the correct virutalenv.

ctypes example

The library documentation on ctypes can be found here.

If we start from scratch in Visual Studio, we can create a solution that contains two projects: a simple Python program to demonstrate ctypes, and a simple DLL from the VS wizards.

Quoting verbatim from the Python docs: ctypes exports the cdll, and on Windows windll and oledll objects, for loading dynamic link libraries. So by using the LoadLibrary method on cdll we can load our DLL into Python, and then start accessing the methods.

The following Python except demonstrates this in practice:

Python
#dll_path = '....'
print "Loading dll {0}".format(dll_path)

#  load it
mydll = cdll.LoadLibrary(dll_path)

#  function has to be extern "C" and have an undecorated name:
result = mydll.fnSimpleDll()
print "Function returned:  {0}".format(result)

#  first way to call C++ decorated method - by ordinal
cppFunction = mydll[1]
cppresult = cppFunction()
print "C++ decorated function by ordinal returned:  {0}".format(cppresult)

#  second way - by decorated name
newCppFunction = getattr(mydll, "?cppFunction@@YAHXZ")
newCppResult = newCppFunction()
print "C++ decorated function by ordinal returned:  {0}".format(newCppResult)

print "Finished"

Using depends, we can examine our DLL and see the ordinals and decorated names (or use a .def file if we really want to). Prefixing functions in C++ with extern "C" makes them directly available in Python as if they were a standard Python module as the function names are undecorated.

For a library or project where you use code generation, you can easily generate a Python stub to your DLLs or .so files that is available cross platform. Other obvious uses are to use Python as a harness for your C/C++ DLLs and run Python based tests against them: this can be particularly useful when Python has some benefit or feature that C++ does not have built-in or available in your environment, that you might want to take advantage of during testing, such as Regular Expressions, REST calls, and so on.

Attached is a Zip file containing the example shown here.

  • PythonCTypes.zip (requires VS2010, Python 2.7, PTVS, and a virtualenv as described above).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)