Mutual calls between Python and C (Python c api and Python ctypes Library)

Source: Internet
Author: User

Write by nine days Yan Ling (jtianling) -- blog.csdn.net/vagrxie

Discuss newsgroups and documents

I implemented "onekeycodehighlighter
"

Some minor issues encountered in, you need to implement global shortcuts, but in fact QT does not provide support for global shortcuts, so QT can only be used through WIN32API, and I, it uses pyqt and python to call Win32 APIs. In fact, there is no difficulty.

Because of the popularity of Python, open-source communities develop their own call methods for mutual calls between Python and C according to their hobbies, this includes using Python C APIs, including the python standard library ctypes, and a bunch of various binding schemes such as sip, boost: Python, what programs are popular in Python? The boost library is known as the quasi-standard library C ++. the only language other than C ++ that supports it is Python, python is also the 3rd languages supported by Symbian in addition to C ++ and Java. At the original company, I still thought that python was a new gadget, I want to encourage Python C API very fresh, (in fact, the original company did not use Python people) to a new company, Ah ~~~ The company only allows 3 Chinese languages, C ++, Java, and python. Everyone is familiar with Python and is very familiar with it. It is often used to develop some tools and scripts, the world is different from what I imagined.
Here we will sort out the python c api knowledge used in previous work and the ctypes library recently used.

Python C API

For this part, refer to my original article Python
C
API
Usage experience...

Here are some actual examples. It turns out to be a rough description of the process.
A month later, when I started learning Python (I am not a veteran ).... Ctypes does not exist yet. At that time, we were all honest in C language, calling Python C
The API is used to call C language functions from Python. I am still thinking about Python. Haha, Haha, I have learned C/C ++ before, and I can call C functions very skillfully.
How amazing is the python c api to complete the task of calling Win32 API in Python? :) it feels like, hey, isn't Python amazing .... There is no way to escape from the control of C language .... At this point, K & R are shown in the picture .... Guido van rosum cried while holding his head under them .......
At that time, the situation was probably like this:

Preparations:

Let's talk about Python c api. In fact, the python c api is much clearer than the Lua API, which also conforms to the pythonic style. Even then, the python c api is designed for C language users, this style is much better than the compilation interface of Lua API (it is said that each data can be operated directly for efficiency.
To use the python c api, you cannot use a common Binary Package. You must use the source code package. Here I use the source code package 3.1.1 as an example: Source Distribution

Python source code has been completely changed to vs2008 in the Windows version. You can directly use vs2008 to open the project under the pcbuild directory, for vs2005 and earlier users, open other version projects under the PC directory. We will compile the pythoncore of the debug version to get two files: python31_d.lib and python31_d.dll. the header file is in the include directory and you need to add pyconfig. the H file is copied from the pcbuild directory to the include file. (You can specify it directly.) The preparation is complete.

Python c api can be used in two ways: Calling Python scripts from C and using C to expand python.
First, let's simply call python from C, that is, embedded python in C.

Embedded python in C

To create a new project, you first need to set the working directory to the Python-3.1.1PCbuild, to obtain the dynamic library, as to the static library inclusion, include directory specified, that is naturally indispensable. The file must contain python. H files, which is also required.
Interface
Py_initialize ();
Py_finalize ();
A pair of calls is required. One is used to initialize the dynamic library of Python and the other is used to release python. [31818 refs] will be output during release, meaning unknown.

Pyrun_simplestring

It can be used to execute simple Python statements. As follows:



# Include
"Python. H"

Int

Main (Int

Argc,Char

* Argv [])
{
Py_initialize ();

Pyrun_simplestring ("Print (
"
Hello World
"
)"
);
Py_finalize ();

System ("pause"
);
Return

0
;
}

 

In this case, the output is:

Hello World
[31829 refs]
Press any key to continue...

 

In this case, you can execute some Python statements. In particular, the python statement execution is in the same execution environment between a py_initialize (); and a py_finalize, what do you mean? Let's see the example.



Int

Main (Int

Argc,Char

* Argv [])
{
Py_initialize ();

Pyrun_simplestring ("str =
"
Hello World
"
"
);
Pyrun_simplestring ("Print (STR )"
);

Py_finalize ();

System ("pause"
);
Return

0
;
}

This example is the same as the output in the previous example. Do you understand what I mean? This means that the previously executed statements are effective for subsequent statements, which is equivalent to sequential execution of statements in the same interactive command line.

Get Return Value

Pyrun_simplestring has some disadvantages. The descriptions in this document are:

Returns 0
On success or
-1
If an exception was
Raised.

You cannot transmit any information in Python or C. We need functions of advanced points.

 

Pyobject * pyrun_string (const char * STR, int start, pyobject * globals, pyobject * locals)
This is what we do.
However, it is important to note that some parameters of this function cannot be obtained if they are left blank, as shown in the following example:


# Include
"Python. H"

Int

Main (Int

Argc,Char

* Argv [])
{
Py_initialize ();

Pyrun_simplestring ("x = 10"
);
Pyrun_simplestring ("Y = 20"
);
Pyobject * mainmodule = pyimport_importmodule ("_ main __"
);
Pyobject * dict = pymodule_getdict (mainmodule );
Pyobject * resultobject = pyrun_string ("X + Y"
, Py_eval_input, dict, dict );

If

(Resultobject)
{
Long

Result = pylong_aslong (resultobject );
Printf ("
% D
"
, Result );
Py_decref (resultobject );
}

Py_finalize ();

System ("pause"
);
Return

0
;
}
Here I use a knowledge, that is
Pyrun_simplestring actually stores all the code in
_ Main __

Run in the module. Note that if the correct module and Its dict are not imported, the Operation will fail and the failure will be miserable. So far, the C language has had an interaction with python.
Haha, I suddenly felt that there was no end to going deep ....... Click here.
For more information, see Programming python. In the woodpecker
I have this book and some translations. Part VI: integration part chapter 23. Embedding python, with relevant knowledge.

Use C to expand Python

This section is described in Chapter 22. Extending python of programming python.
We can only get started here. We can tell you at most that, in fact, there is no difficulty in all this. Python
C
API
Usage experience...

It is described in the article.
The configuration is similar to the one mentioned above. Generally, a dynamic library is generated when python is expanded using C, but the suffix of the dynamic library is set. PYD. Only in this way will the data be automatically queried during import.
In addition, there are several fixed naming rules to follow for python write extensions.
First, let's look at the built-in example:


# Include
"Python. H"

Static

Pyobject *
Ex_foo (pyobject * Self, pyobject * ARGs)
{
Printf ("Hello, world
N
"
);
Py_incref (py_none );
Return

Py_none;
}

Static

Pymethoddef example_methods [] = {
{"Foo"
, Ex_foo, meth_varargs, "Foo () Doc string"
},
{Null
, Null
}
};

Static

 Struct

Pymoduledef examplemodule = {
Pymoduledef_head_init,
"Example"
,
"Example module Doc string"
,
-1
,
Example_methods,
Null
,
Null
,
Null
,
Null

};

Pymodinit_func
Pyinit_example (Void

)
{
Return

Pymodule_create (& examplemodule );
}

This example contains the basic information of all C language extensions for Python:
1. pyinit_example is the final exit. It should be noted that example not only indicates the meaning of example, but also indicates that the generated library will be named by example, that is, you will need to use
Import example

.
2.Static

 Struct

The existence of pymoduledef examplemodule is also required and the information of the entire module is specified. For example
"Example module Doc string", the description of the module. The meaning of each parameter has been illustrated above.
For more information, see pymoduledef.
3. example_methods is a list of functions. In fact, it indicates the functions contained in this module. This example only contains
Foo is a function.
Static

Pyobject *
Ex_foo (pyobject * Self, pyobject * ARGs)
{
Printf ("Hello, world
N
"
);
Py_incref (py_none );
Return

Py_none;
}

Is the specific implementation of the entire function. This function indicates whether to output "Hello, world" or "Hello world ........ This world is really busy .... Someone say hello every day.

The example included in this python is a little too simple. I will give a slightly more complex example, or my favorite MessageBox, the final effect is naturally Hello world ...........

# Include

Static

Pyobject *
MessageBox (pyobject * Self, pyobject * ARGs)
{
Lpcstr lptext;
Lpcstr lpcaption;
Uint utype;

Pyarg_parsetuple (ARGs, "ssi"
, & Lptext, & lpcaption, & utype );

Int

Result = messageboxa (0
, Lptext, lpcaption, utype );

Pyobject * resultobject = py_buildvalue ("
% I
"
, Result );

Return

Resultobject;
}

Static

Pymethoddef c_methods [] = {
{"MessageBox"
, MessageBox, meth_varargs, "MessageBox ()"
},
{Null
, Null
}
};

Static

 Struct

Pymoduledef win32module = {
Pymoduledef_head_init,
"WIN32API"
,
"Win32 API MessageBox"
,
-1
,
C_methods,
Null
,
Null
,
Null
,
Null

};

Pymodinit_func
Pyinit_win32api (Void

)
{
Return

Pymodule_create (& win32module );
}


Note that the only difference is that I have parameters passed in from Python and returned values from C.
Pyarg_parsetuple
Used to parse parameters
Py_buildvalue is used to construct a python value to return
Their build and resolution forms are a bit similar to C Common forms such as sprintf, but each character represents something different. Note that the document is more detailed, this example shows the conversion of string and Int.

After this file is compiled as a dynamic library, it is specified as WIN32API. the PYD file, and then copy it to the directory where python_d is located (the debug version Python generated using python3.1.1 source code). At this time, the import will first find * _ d. A dynamic library in PYD form. Otherwise, only the release version will be searched.
First, let's look at the database information:

>>> Import WIN32API
[44692 refs]
>>> Dir (WIN32API)
['Messagebox', '_ Doc _', '_ file _', '_ name _', '_ package _']
[44705 refs]
>>> Help (WIN32API)
Help on module WIN32API:

Name
WIN32API-Win32 API MessageBox

File
D: python-3.1.1pcbuildwin32api_d.pyd

Functions
MessageBox (...)
MessageBox ()

[68311 refs]
Have you noticed the role of the document? We also noticed the power of dir ............. At this time, MessageBox is already in WIN32API. Call it directly. The handle of the window is ignored.

What a busy world ........
At this point, you will think that it is too powerful. I will put the entire Win32 API everywhere, so Python will be able to operate the entire operating system like the C/C ++ language, and, this is dynamic !!!!
That's right, but how much work is needed ...... However, python is so popular that some people always do such a thing, so pywindows was born. Install one, so you have everything.
>>> Import WIN32API
>>> WIN32API. MessageBox (0, "great", "Hello World", 0)
1
In this way, all the above results can be achieved ...........

Python ctypes

In this case, python is still inseparable from C (although Python itself is written in C .... A year later, ctypes was born, so people who do not understand the C language can also directly use python to do this. There is no doubt that python is becoming more and more self-contained. Their goal is that there are no other languages! -_-! As described in Python v3.1.1,
Ctypes
-A foreign
Function library for python
Then: it can be used to wrap these libraries in pure python.
Note that they want pure python! (I don't want to provoke a language war .....)
Guido van rosum started to say that wrap these, in pure python .... Do not use the foreign language any more.

Let's talk less about it. Look at ctypes. It looks very simple because it is pure python. In fact, the document is also quite detailed (of course, some details are missing ), the following uses python3.1.1 in Windows as an example:
>>> Import ctypes
>>> From ctypes import *
>>> Dir (ctypes)
['Array', 'argumenterror ', 'array', 'bigendiance', 'cdll', 'cfunctype ','
Default_mode ', 'dlcanunloadnow', 'dlgetclassobject ', 'formaterror', 'getlaster
Ror ', 'hresult', 'libraryloader', 'littleendianstructuring ', 'oledll', 'pointer ',
'Pyfunctiontype', 'pydll ', 'rtld _ global', 'rtld _ local', 'setpointertype', 'structure
', 'Union', 'winfunctype ', 'windll', 'winerror', '_ cfuncptr', '_ funcflag_cdecl ',
'_ Funcflag_pythonapi', '_ funcflag_stdcall', '_ funcflag_use_errno', '_ funcflag_u
Se_lasterror ',' _ pointer ',' _ simplecdata ',' _ builtins _ ',' _ Doc _ ',' _ file __'
, '_ Name _', '_ package _', '_ path _', '_ version _', '_ c_functype_cache ', '_ c
Alcsize ',' _ cast', '_ cast_addr', '_ check_hresult', '_ check_size', '_ ctypes_versi
On ',' _ dlopen ',' _ endian ',' _ memmove_addr ',' _ memset_addr ',' _ OS ',' _ pointer_typ
E_cache ',' _ string_at ',' _ string_at_addr ',' _ sys ',' _ win_functype_cache ',' _ wstr
Ing_at ',' _ wstring_at_addr ', 'address', 'alignment', 'byref ', 'c _ bool', 'c _ Buf
Fer ', 'c _ byte', 'c _ char', 'c _ char_p ', 'c _ double', 'c _ float', 'c _ int ', 'C _ int16 ',
'C _ int32 ', 'c _ int64', 'c _ int8', 'c _ long', 'c _ longdouble', 'c _ longlong', 'c _ shor
T', 'c _ size_t ', 'c _ ubyte', 'c _ uint', 'c _ uint16', 'c _ uint32 ', 'c _ uint64 ', 'C _ uint
8 ', 'c _ ulong', 'c _ ulonglong', 'c _ ushort', 'c _ void_p ', 'c _ voidp', 'c _ wchar ', 'C _ w
Char_p ', 'cast', 'cdll', 'create _ string_buffer ', 'create _ unicode_buffer', 'Get _ e
Rrno', 'Get _ last_error ', 'memmove', 'memset', 'oledll ', 'pointer', 'py _ object ',
'Pydll ', 'pythonapi', 'resize', 'set _ conversion_mode ', 'set _ errno', 'set _ last_er
Ror ', 'SIZE', 'string _ at', 'windll', 'wstring _ at']

There are a lot of things contained in such a gadget. We can see that it mainly includes some Type Definitions in C language.
When you import ctypes, some dynamic libraries have been loaded:
>>> Print (Windll. Kernel32)

>>> Print (Windll. USER32)

>>> Print (Windll. msvcrt)

Let's try it directly. Our favorite is Hello world. MessageBox is called directly here. Check msdn and MessageBox in USER32. We will call it.
>>> MessageBox = Windll. user32.messageboxw
>>> MessageBox (0, "great", "Hello World", 0)
Then, MessageBox is called ........

Why? Dizzy? Compare the ctypes library and Python c api .... So k & R cried .............
Start with a story

End:

 

The author of the original article retains the copyright reprinted. Please indicate the original author and give a link

Write by nine days Yan Ling (jtianling) -- blog.csdn.net/vagrxie

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.