C + + Extended Python Instance learning tutorial

Source: Internet
Author: User
Tags extend object model wrapper python list in python

It's easy to write with Python scripts, and we'll learn to use C/c++python to extend the example.



Description: The operating system in the test environment is Centos6.5_x64,python version 2.6


call a dynamic library directly

1. Write the dynamic Cuven code of the module

Here for the maximum number of examples

Code (CALLTEST1.CPP) is as follows:


extern "C"
{
int Max (int i1,int i2)
{
Return (I1>I2) I1:i2;
}
}



Execute the following command in bash:

g++-fpic-shared-o libcalltest1.so CallTest1.cpp

Generating Dynamic Library files libcalltest1.so

2. Using Python to invoke dynamic libraries

Dynamic library files can be invoked through cTYPES, as follows:


#! /usr/bin/env python

From ctypes Import *
Import OS

SO1 = Cdll (OS.GETCWD () + '/libcalltest1.so ')
Print So1. Max (1,3)


using the Boost library to extend Python

This way you can directly generate Python modules, using the import operation directly. Of course, the use of this way, need to install boost library, the specific operation here will not say, do not understand the friends themselves check.

Boost official website: http://www.boost.org/

1, the module code is as follows:

FileName: boostCallTest1.cpp

File contents:


int Max (int i1,int i2)
{
Return (I1>I2) I1:i2;
}

#include
#include
Using namespace boost::p Ython;

Boost_python_module (BoostCallTest1)
{
def ("Max", Max);
}



2, write the module compilation script

FileName: setup.py

File contents:


#!/usr/bin/env python

From Distutils.core Import Setup
From distutils.extension Import extension

Setup (name= "PackageName",
ext_modules=[
Extension ("BoostCallTest1", ["BoostCallTest1.cpp"],
libraries = ["Boost_python"])
])



3, compile the module and test

Compile module:

Python setup.py Build

Generates boostcalltest1.so files in the build directory, which can be used as follows:

>>> Import BoostCallTest1
>>> Boostcalltest1.max (1,3)
3

using Swig to extend Python

Swig is a development tool that helps software written in C or C + + to embed joins with various other advanced programming languages.

Swig can be applied to a variety of different languages including common scripting languages such as Perl, PHP, Python, TCL, Ruby and PHP.

Swig official website: http://www.swig.org/download.html

Can be installed directly via Yum:

Yum Install Swig

1, write program code

FileName: swigCall.cpp

The contents are as follows:

int Max (int i1,int i2)
{
Return (I1>I2) I1:i2;
}

2. Write Interface file

FileName: swigcall.i

The contents are as follows:

%module Swigcall
%{
extern int Max (int i1,int i2);
%}

extern int Max (int i1,int i2);

3, the preparation of makefile documents

The contents are as follows:

All
Make Swigcall

Swigcall:
Swig-python-c++ swigcall.i
g++-C swigCall.cpp swigcall_wrap.cxx-i/usr/include/python2.6/-fpic
g++-shared SWIGCALL.O Swigcall_wrap.o-o _swigcall.so

Clean
Rm-f swigcall_wrap.c*
Rm-f *.py*
Rm-f *.so
Rm-f *.O

Note: To compile C + + code using the-c++ parameter in the Swig command


using SIP extensions python

SIP is developed from Swig and is used specifically for Python calls to C + + modules. Note that SIP is not the same thing as the SIP in VoIP, where the SIP is extended python, and the SIP in VoIP is a communication protocol and don't confuse it.

Attention:

Need to install the Python SIP library;

1. Write C + + module

1.1 Writing header files

File name: SipCall.h file contents:

Class Testmode
{
Public
int Max (int i1,int i2);
};

1.2 Writing module Content

File name: SipCall.cpp file contents:


#include "sipCall.h"

int Testmode::max (int i1,int i2)
{
Return (I1>I2) I1:i2;
}



2. Write Interface file

File name: Sipcall.sip file contents:

%module Testmode

Class Testmode {

%typeheadercode
#include "sipCall.h"
%end

Public
int Max (int i1,int i2);
};

3, the survival of Static library

This is accomplished with a script, file name: genlib.sh

File contents:

#! /bin/bash
g++-c-fpic SipCall.cpp
Ar-crs LIBSIPCALL.A SIPCALL.O

4, the preparation of configure documents

This script is used to generate makefile, which reads as follows:


#! /usr/bin/env python

Import OS
Import Sipconfig

Build_file = "SIPCALL.SBF"
Config = sipconfig. Configuration ()
cmd = "". Join ([Config.sip_bin, "-C", ".", "B", Build_file, "Sipcall.sip"])
Os.system (CMD)

Makefile = Sipconfig. Sipmodulemakefile (config, build_file)
Makefile.extra_libs = ["Sipcall"]
Makefile. Libdir.append (".")
Makefile.generate ()



5, run genlib.sh script to generate LIB file;

6, run configure.py script generation makefile;

7, run make Generate module file (so file);

8, the Python test is as follows:

>>> Import Testmode
>>> dir (testmode)
[' Testmode ', ' __doc__ ', ' __file__ ', ' __name__ ', ' __package__ ']
>>> s = Testmode.testmode ()
>>> S.max (1,3)
3

This article GitHub address:

Https://github.com/mike-zhang/mikeBlogEssays/blob/master/2015/20150808_ extended python.md with C + +

python S/C + + extensions

Extensibility is a major feature of Python, on the one hand, because Python interprets execution, which results in slower running than the compiled language, you can use the C + + Rewrite the core code to solve the performance bottleneck (90% of the time to run 10% of the Code), on the other hand, you can extend it to add some additional functionality and maintain proprietary source code. In the next section of this article, we'll discuss how to write C + + extension code and use their functionality.
We're going to build a C + + module that can run in Python, so we need to address how to make the C code and Python code interactive and data-sharing. An extension enables bidirectional interaction and data sharing by writing wrapper functions (like adapters) for C code.

One. General wrapper mode

Each wrapper function mainly does three things:
1. Converts the input Python object to a C + + object;
2. Call C/n + + function;
3. Convert C + + The output of the function processing is the Python object and returns;

First describes the overall process of the module with a simple sample:

Wrap.cpp//1.c code #include   "Python.h" Int add (int arg1, int arg2) {   
 return arg1 + arg2; //2.add wrapper function: Static pyobject* wrap_add (Pyobject *self, pyobject *args) {  
  //converts the input Python object to the data that is recognized by C + +     int arg1, arg2;     if (!
Pyarg_parsetuple (args,  "II",  &ARG1, &ARG2))     return NULL;
    //calls the C + + function, obtains the result     int result = add (ARG1,ARG2);     //the resulting results into a Python object and returns to the     return  (pyobject*) py_buildvalue ("I
",  result);} 3. Add the Pymethoddef method array to the module static pymethoddef wrap_methods[] ={    {"Add",
 wrap_add, meth_varargs},     {null, null}}; 4. Add module initialization function Initmodule pymodinit_func initwrap  (void) {     py_initmodule ("wrap ",  wrap_methods); }



Compile the code above to generate Wrap.pyd.

Start the console switch to the appropriate engineering directory to test the generated module:

(PS: Only modules generated by release mode appear to function correctly)

Related instructions

Each wrapper function has the following form:
Pyobject * Wrap_function (Pyobject *, Pyobject * args)
The first parameter of the function, which has a special purpose, is usually ignored. The second parameter is a pytuple (Pyobject subtype, which corresponds to the tuple in Python) and is the parameter that Python passed in when invoked.
The function Pyarg_parsetuple converts the Python object to the data type of C, which is declared as follows:
int Pyarg_parsetuple (pyobject* args, char* format, ...);
The parameter args must be a tuple object that contains the arguments passed over, and the format argument must be a formatted string. The remaining arguments are the addresses of the individual variables, and the type corresponds to the formatted string. Such as:
int arg1, arg2;
Pyarg_parsetuple (args, "II", &arg1, &ARG2);
A function py_buildvalue can be said to be a pyarg_parsetuple inverse process that wraps the data type of C as a Python object.
Return (pyobject*) py_buildvalue ("I", result);
Wrap the result of the call to the C function as the Python int object and return.
Static Pymethoddef wrap_methods[] ={
{"Add", Wrap_add, Meth_varargs},
{NULL, NULL}
};
This array contains multiple arrays, each of which contains information about a function so that the interpreter can import and invoke them, and the last null array represents the end of the list. Meth_varargs constants represent arguments that are passed in as tuples.
Pymodinit_func initwrap (void)
{
Py_initmodule ("wrap", wrap_methods);
}
Module initialization function void Initmodulename (), which is called by the interpreter when the module is imported. So all the packaging is done.

two. Packaging for C + + classes

 example.cpp class numbers {public:     numbers (int first, double 
Second)         : m_first ( first),  m_second (second) {}     double nummembermult (void) { return m_first*m_second;} private:  
   int m_first;
    double m_second;
}; Static void pydelnumbers (void *ptr) {    numbers * oldnum =
 static_cast (PTR);
    delete oldnum;
    return; } pyobject *example_new_numbers (Pyobject *, pyobject* args) {    int
 arg1;
    double arg2;
    int ok = pyarg_parsetuple (args, "id", &ARG1,&ARG2);
    if (!ok)  return NULL;    //dynamically creates a new object     numbeRs *newnum = new numbers (ARG1, ARG2);    //wraps the pointer newnum into a Pycobject object and returns it to the interpreter     return pycobject_fromvoidptr (
 newnum, pydelnumbers); } pyobject * example_numbers_membermult (Pyobject *, pyobject* args) {   
 PyObject *pynum = 0;
    int ok = pyarg_parsetuple ( args,  "O",  &pynum);
    if (!ok)  return NULL;    //converts pycobject to void pointer     void * temp = pycobject_
Asvoidptr (Pynum);    //converts a void pointer to a Numbers object pointer     Numbers * thisnum = 
Static_cast (temp);     //Call Function     double result = thisnum->nummembermult
();
    //returns results     return py_buildvalue ("D", result); } Static pymethoddef example_methods[] = {    {"Numbers",  example_new_numbers,  meth_varargs},     {"Nummembermult",  example_numbers_membermult, meth_
VARARGS},     {null, null}}; pymodinit_func initexample  (void) {    py_initmodule ("Example",  example_
methods); }


C + + class packaging and C function packaging is similar, because the packaging of classes is a function of the wrapper, so still need to use Python code to wrap the expansion module, can be used like a class.

#example. py from
Example Import *
class Example (object):
def __init__ (self,arg1,arg2):
self._b ASE = Numbers (arg1,arg2)
def membermult (self): return
Nummembermult (self._base)




So the C + + class wrapper is complete.

Three Create a Python list in C + +

Static pyobject* windy_dict (Pyobject *self, Pyobject *args)
{
//Create List
pyobject *newlist = pylist_new (0)    ;
Pylist_append (NewList, pystring_fromstring ("a");
Pylist_append (NewList, Pystring_fromstring ("second"));
Pylist_append (NewList, Pystring_fromstring ("third"));
Returns to interpreter return
newlist;
}


Creating other Python objects is similar to creating a list, and returning to the interpreter is an object pointer. The parsing of the Python object by C/s + + is almost the inverse process of creation. The specific object model and API can refer to the relevant reference documentation.

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.