Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Mutual calls between Python and C (Python C API and Python ctypes libraries)

2025-01-15 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/03 Report--

Problem, need to implement global shortcuts, but in fact Qt does not provide support for global shortcuts, then using Qt can only be done through Win32Api, and I, using PyQt, but also need to use Python to call win32 API, in fact, it is not difficult.

Because Python is so popular, the open source community has developed its own way of calling each other between Python and C according to their own hobbies, including using Python C API, including ctypes, the Python standard library, and a lot of various binding schemes such as SIP,Boost::Python. You should know what programs are popular in Python. Boost library is known as the C++ quasi-standard library. The only language other than C++ is supported by Python,Python, which is the third language supported by Symbian in addition to Java. At that time, I always thought Python was a new gadget in my original company, and it was fresh when I was asked to tinker with Python C API. (in fact, people who did not use Python in the original company) came to the new company. Ah, the company is only allowed to use 3 languages, Java, and Python. And we are familiar with Python, easy to use, often used to develop some tools and scripts, hehe, the world is different from what I imagined.

Here we sort out the knowledge of Python C API used in previous work and the knowledge of the ctypes library that has been used recently. Python C API

This section can refer to my original article, "experience in using python c api." here are just some practical examples, which turns out to be a general description of the process.

Some year, some month, when I began to learn the ancient years of Python (I am not relying on the old to sell the old). Ctypes does not exist yet. At that time, we all honestly used C language to call Python C API to complete the task of calling C language functions from Python. When I was learning Python, I was still thinking, ha, I used to learn C _ Python C API, I can very skillfully call Python C API to complete tasks such as Python calling Win32 API, how amazing I am:) at this time, I feel like, hey, Python, aren't you great. There is no way to escape the clutches of C language. At this time, what appears in the picture is the sneer of Kendr hey hey. Guido van Rossum cried with her head in her arms at their feet.

At that time, the situation went something like this:

Preparatory work:

Cut the gossip and look at Python C API. In fact, Python C API is much clearer than Lua's API, which is also in line with the style of Pythonic. Even if Python C API is designed for C language users at this time, it is still this style, which is much better than the assembly-style interface of Lua API (it is said that every data can be manipulated directly for efficiency).

To use Python C API, it is not possible to use an ordinary binary package, you have to go under the source code package. Here I use the 3.1.1 source package as an example: Source Distribution

The source code of Python has been completely changed to VS2008 in the version of Windows. Just open the project in the PCbuild directory with VS2008. For VS2005 and previous users, open other versions of the project in the PC directory. When we compile the debug version of pythoncore, we will get two python31_d.lib,python31_d.dll files, the header file we need is in the Include directory, and we also need to copy the pyconfig.h file from the PCBuild directory to Include. (you can specify it directly) so that the preparation work is done.

Python C API can be used in two ways, calling Python scripts from C # and extending Python with C.

Let's start with a simple call to Python from C, which is often called embedding Python in C.

Embedded Python in C

To establish a new project, you first need to set the working directory to Python-3.1.1PCbuild to get the dynamic library. As for the inclusion of the static library and the designation of the Include directory, it is also necessary. Python.h files need to be included in the file, which is also required.

Interface

Py_Initialize ()

Py_Finalize ()

A pair of calls are required, one for initializing the Python dynamic library and one for releasing. When released, [31818 refs] is output, the meaning is unknown.

PyRun_SimpleString

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

}

At this point, the output is:

Hello World

[31829 refs]

Please press any key to continue. . .

At this point, some Python statements can be executed, and, in particular, between a Py_Initialize (); and Py_Finalize ();, Python statements are executed in the same execution environment. What do you mean? Just look at an 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 of the above example, see what I mean? It means that previously executed statements are valid for subsequent statements, which is equivalent to executing statements sequentially on the same interactive command line.

Get the return value

PyRun_SimpleString has some disadvantages, as described in the document:

Returns 0 on success or-1 if an exception was raised.

Then you won't be able to convey any messages in Python and C. We need a more advanced function.

PyObject* PyRun_String (const char * str, int start, PyObject* globals, PyObject* locals)

That's what you do.

However, it is important to pay attention to the acquisition of some parameters of this function, and it is not possible to leave them empty as a matter of course, 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 take advantage of the knowledge that PyRun_SimpleString actually runs all the code in the _ _ main__ module. Note that if you don't import the correct module and its dict, you will fail and fail miserably. At this point, the C language has interacted with Python.

Hehe, I suddenly feel that there is no end if I go deeper. Let's call it a day.

If you go a little deeper, you can read "Programming Python". There is this book and some translations on the woodpecker. Part VI: Integration part Chapter 23. Embedding Python, have relevant knowledge.

Using C # to expand Python

This section is in Chapter 22 of "Programming Python". It is introduced in the Extending Python section.

Here can only start, at most tell you, in fact, these are not difficult. A slightly more complicated situation is introduced in the article "experience in using python c api."

Configuration is similar to what was mentioned above, generally speaking, extending Python with C # will eventually generate a dynamic library, but the suffix of this dynamic library will be set to .pyd. Only in this way will it be automatically queried when import.

In addition, write extensions for Python to follow Python's set of rules, fixed several names.

First of all, let's take a look at the example that comes with it:

# 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 all the basic information when the C language writes extensions for Python:

1.PyInit_example is the last exit, and it should be noted that example not only represents the meaning of example, but also means that the resulting library will be named with example, that is, you will need to use the

Import example

In the form of.

The existence of 2.static struct PyModuleDef examplemodule is also necessary, specifying the information of the entire module, such as "examplemodule doc string" above, and the description text of the module. The meaning of each parameter has been demonstrated above. For all the contents, you can refer to the instructions on PyModuleDef in the documentation.

3.example_methods is a list of functions that actually represent the functions contained in this module. There is only one function called foo in this example.

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 represents the output "Hello, world", or hello world. This world is really busy. There are say hello people every day.

The example that comes with Python itself is a bit too simple. I'll give you a slightly more complicated example, which is still my favorite MessageBox, and 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 here I have the parameters passed in from Python and the return values passed out from C.

PyArg_ParseTuple is used to parse parameters

Py_BuildValue is used to build the value return of a Python

Their build and parsing forms are somewhat similar to the common C forms such as sprintf, but each character does not necessarily represent the same thing, it should be noted that the document is more detailed, this example shows the conversion of String and int.

After compiling this file as a generated dynamic library, specifying it as a Win32API.pyd file, and then copying it to the directory where Python_d is located (debug version Python generated with Python3.1.1 source code), import will first look for dynamic libraries in the form of * _ d.pyd, otherwise only the release version will be searched.

First, take a look at the information in the library:

> import Win32API

[44692 refs]

> dir (Win32API)

['MessageBox',' _ doc__','_ _ file__','_ _ name__','_ _ package__']

[44705 refs]

> help (Win32API)

Help on module Win32API:

NAME

Win32API-Win32API MessageBox

FILE

D:python-3.1.1pcbuildwin32api_d.pyd

FUNCTIONS

MessageBox (...)

MessageBox ()

[68311 refs]

Did you notice the role of the document? Also noticed the power of dir. MessageBox is already in Win32API, so call it directly. I have ignored the handle of the window here, which needs to be noted.

What a busy World.

At this point you will think, too powerful, I'm going to put the entire Win32 API everywhere, so Python can fully operate the entire operating system like the Cpicurus + language, and it's still dynamic!

Yes, but what a lot of work. However, Python is so popular that there are always people who do such a thing, so PyWindows is born. To install one, so you have everything.

> import win32api

> win32api.MessageBox (0, "Great", "Hello World", 0)

one

In this way, all the above effects can be achieved.

Python ctypes

In this way, it turns out that Python is still inseparable from C (although Python itself is written in C). Until. In a certain year and a certain month, ctypes was born, so people who do not understand the C language can also directly use Python to complete this kind of work. There is no doubt that Python is becoming more and more self-contained, and their goal is that there are no other languages! -_! As described in the documentation for Python v3.1.1

Ctypes-A foreign function library for Python

Then: It can be used to wrap these libraries in pure Python.

Attention, they want Pure Python! I'm not trying to start a language war. )

Guido van Rossum began to say, wrap these,in pure Python. Don't use the foreignlanguage any more, guys who don't have pure blood.

To cut the gossip, take a look at ctypes. Because it is pure Python, it looks very simple. In fact, the document is quite detailed (of course, some details are left out). Here is an example of the operation of Python3.1.1 in Windows:

> import ctypes

> from ctypes import *

> dir (ctypes)

['ARRAY',' ArgumentError', 'Array',' BigEndianStructure', 'CDLL',' CFUNCTYPE','

DEFAULT_MODE', 'DllCanUnloadNow',' DllGetClassObject', 'FormatError',' GetLastEr

Ror', 'HRESULT',' LibraryLoader', 'LittleEndianStructure',' OleDLL', 'POINTER'

'PYFUNCTYPE', '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__','_ cations functionally cachets,'_ c

Alcsize','_ cast','_ cast_addr','_ check_HRESULT','_ check_size','_ ctypes_versi

On','_ dlopen','_ endian','_ memmove_addr','_ memset_addr','_ os','_ pointer_typ

EBay cachets,'_ string_at','_ string_at_addr','_ sys','_ win_functype_cache','_ wstr

Ing_at','_ wstring_at_addr', 'addressof',' alignment', 'byref',' canals Boolean, 'c_buf

Fer', 'caster chartered,' catered floatable, 'caterpillar intact,' clockint16'

'clocked int32, 'clocked int64,' clocked int8, 'caged longitude,' caged longitude, 'caged longevity,' c_shor

Tweets, 'cymbals sizeboxes,' cedars ubytems, 'cymbals uintals,' cymbals uint16, 'cymnuint32, cymbals uint64,' c_uint

Eight, three, six, eight, eight, two, three, two, three, two, two,

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', 'sizeof',' string_at', 'windll',' wstring_at']

Such a gadget contains a lot of things, you can see that it mainly includes some C language type definitions.

When you import ctypes, some dynamic libraries are already 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 that MSDN,MessageBox is in User32, and we call it.

> MessageBox = windll.user32.MessageBoxW

> MessageBox (0, "Great", "Hello World", 0)

Then MessageBox is called.

Http://blog.csdn.net/vagrxie/article/details/5251306

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report