Mutual invocation of C + + and Python

Source: Internet
Author: User
Tags gettext python list

The "editor's note" has recently been sending Python data because of Python's scripting extensibility. The dynamic language features of. NET are now very powerful, and it seems that the script does not work as clearly. But for the old-fashioned C + +, if you can combine the dynamic nature of scripting language, quoting the latest popular sentence: Must be able to form management! C + + Call Python can be implemented through the API, or through the Boost library, Boost.python is the packaging of the API, convenient to call.

This is a relatively old introduction Boost.python article, right when the introduction of it. Because some things in the text are not right now ...

Boost.python is a component of boost, which can greatly simplify the process of writing extensions to Python in C + + and improve development efficiency, although it is not a lot of support for Python embedded C + +, but it also provides great convenience. In addition, Huayu has written a concise tutorial on Boost.python.

1 Boost Installation Brief

Before we formally start using Boost.python, we must compile Boost first. First , download the boost source package to the boost's official site, unzip it into your favorite directory, and prepare for the build. In addition, before formally installing Boost.python, we must install Python correctly first.

1.1 Compilation under Linux

First, switch to the path where the Boost source code is located, execute the ./configure script, and provide the appropriate parameters for the Python runtime environment for the configuration script:

./configure--with-python=/usr/bin/python/
--with-python-version=2.4/
--with-python-root=/usr

Then, with the vast majority of Linux programs, execution make can start compiling. After compiling, switch to root permissions and then execute make install , the Boost corresponding header files and library files copied to the appropriate place, it can be used.

1.2 Compiling with MinGW + MSys under Windows

The first need to compile is the Boost compiler tool Bjam, directly to the Bjam in the directory, that is, the Boost source package in the directory /tools/build/jam_src , execution build.bat mingw , wait a moment, Bjam.exe compiled well. Copy the compiled Bjam.exe to the %PATH% location where your path can be found directly, and prepare for the subsequent compilation work.

Next, switch to the Boost source path, execute bjam to compile. We need to provide some parameters about Python, the variable python_root points to the directory where the Python run environment is located, the value of the variable python_version is the Python version number, and if your Python installation path differs from that of the Dian Fox, please use the corresponding Change the variable to the appropriate path on your machine, and compile the command line as follows:

Bjam.exe "-stools=mingw" "-spython_root=e:/python" "-spython_version=2.4"

After compiling, you will C:/Boost find the compiled Boost corresponding header file and library file under you, you can move it to another place depending on your needs.

2 embedding Python modules into C + + using Boost.python

Boost.python does not currently provide a complete wrapper library for embedding Python modules into C + +, so many of the work we have to do is through the Python C API. However, the use of some of the modules provided in Boost.python can bring great convenience to our work.

2.1 Modifying the module load path, loading the Python module

As with any other Python-embedded C + + program, we need to include it at the first #include statement Python.h and invoke it at the beginning of the program at the end of the Py_Initialize() program Py_Finalize() .

Next, we're ready to start loading the Python module. In order for the Python interpreter to correctly find the location of the Python module, we need to add the path of the Python module to the module search path, and the Python statement to add the search path is as follows:

Import Sys
if not'/module/path ' inchSys.path:
Sys.path.append ('/module/path ')

We can add the search path of the module to the Python interpreter by executing a similar statement using the Python C API. Once you have added a search path, you can PyImport_ImportModule load the Python module with a function. The PyImport_ImportModule return value is PyObject * , in order to avoid problems such as manual handling of cumbersome reference counts, we turn to the module provided by Boost.python, which handle will be PyObject * encapsulated for ease of use, the code is as follows:

#include

...

Boost::p ython::handle<>* _module; Module handle.
std::string path; Path of the Python module.
std::string module; Module name.

...

Try
{
pyrun_simplestring ("Import sys");
Pyrun_simplestring ((std::string ("if not") + path
+ "' in sys.path:sys.path.append (' + path + ')"). C_str ());
_module = NewBoost::p ython::handle<> (
Pyimport_importmodule (( Char*) module);
...
}
Catch(...)
{
Pyerr_print ();
Pyerr_clear ();
Delete_module;
_module = NULL;
returnfalse;
}

...

It is important to note that the Python interpreter loaded with the Python C API does not include the current path in the default search path. Therefore, even if your Python module is stored in the current path, you must use the code above to add the current path to the search path before it can be PyImport_ImportModule loaded into the module.

When the Python module is finished or the program is finished, use to release the delete _module pointer, release handle the corresponding Python module and reclaim the appropriate resources.

2.2 Calling the Python function

After importing the Python module, it is very easy to call the Python function. Boost.python encapsulates a very useful template function boost::python::call_method that can handle all the details you need to handle when calling a function, from the tedious "package parameters to PyObject * ", "Construct tuple", "pass tuple", and " Unpack return value "and so the work is completely liberated, you only need this:

Boost::p ython::call_method< return value type > (module pointer, "Python function name",
Parameter 1, parameter 2, ...);

The module pointers can be obtained from the methods we obtained earlier _module get , for example:

...
BOOLResult
Std::string config_file;

...

Try
{
returnBoost::p ython::call_method< BOOL> (_module->get (), "Initialize",
Config_file);
}
Catch(...)
{
Pyerr_print ();
Pyerr_clear ();
...
}

... 2.3 Using Python class objects

Using the Python C API to call the Python function and calling the Python class object is not very different, we just need to invoke the constructor method of the class, get a Class object, and then treat the pointer of the class as a module pointer, and call the class member method by calling the normal function method before. For example, the following code _module creates an YukiSession object from, and then invokes the method in it on_welcome . In addition to demonstrating the invocation of a class member method, this code shows how to construct a Python list object and get elements from a Python list object.

...

Boost::p ython::handle<> _yukisession;

...

Retrieve the module handle and namespace handle.
Boost::p ython::object main_module (*_module);
Boost::p ython::object main_namespace = main_module.attr ("__dict__");

Call the method and get the object handle.
_yukisession = boost::p ython::handle<> ((Pyrun_string (
"Yukisession ()", Py_eval_input,
Main_namespace.ptr (), Main_namespace.ptr ()));
...

Compose a list.
Boost::p ython::list param;
Param.append (boost::p ython::str (_addr.get_host_addr ()));
Param.append (boost::p ython::str ());

Call the method and retrieve the result.
Method is equivalent to:
"BOOL __thiscall yukisession::on_welcome (list param);"
result = Boost::p ython::call_method< BOOL>
(_yukisession.get (), "On_welcome", param);
Extract an item from a list.
str = boost::p ython::call_method
(Param.ptr (), "__getitem__", 1);

... 3 calling a C + + program in an embedded Python module

Using Boost.python to export a C + + module to a Python program with a dynamic link library and to export the module to an embedded Python interpreter in a C + + executable program is almost identical in the way it is written. So here's just a brief introduction to the method of exporting common functions, and to learn more about advanced features such as exporting C + + classes, exporting classes that can be overloaded with Python, see Huayu's Boost.python concise tutorials or official Boost.python documentation.

3.1 Exporting C + + functions

First use BOOST_PYTHON_MODULE a macro to define the modules that need to be exported to Python, and then use boost::python::def statements to define the exported functions, parameter lists, and DOC strings, for example, in the following example, we export a C + + function yukigettext and rename it as gettext :

Const Char*yukigettext ( Const Char*ID);

Boost_python_module (Yuki)
{
Boost::p Ython::d EF ("GetText", Yukigettext,
Boost::p Ython::args ("id"), "Translate message.");
} 3.2 initializes the C + + module for Python

With the BOOST_PYTHON_MODULE(name) Python module defined, the macro automatically generates a function, and initname we need to Py_Initialize() call this auto-generated function later to initialize the exported module to Python. For example, we just exported the macro for the module BOOST_PYTHON_MODULE(yuki) , so we should call it when we initialize it inityuki() :

...
Py_initialize ();
Inityuki ();
... 3.3 Calling the C + + module in a Python module

At this point in the Python module we only need to like the normal Python module, the imported C + + module with the import statement loaded in, you can call:

Import Yuki

...

PrintYuki.gettext ("This is a test!")

Original: http://edyfox.codecarver.org/html/boost_python.html

Mutual invocation of C + + and Python

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.