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.