欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

pythonctypes的作用有哪些

這篇文章將為大家詳細(xì)講解有關(guān)python ctypes的作用有哪些,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

成都創(chuàng)新互聯(lián)公司專(zhuān)業(yè)為企業(yè)提供隨州網(wǎng)站建設(shè)、隨州做網(wǎng)站、隨州網(wǎng)站設(shè)計(jì)、隨州網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、隨州企業(yè)網(wǎng)站模板建站服務(wù),十載隨州做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。

ctypes是python的一個(gè)函數(shù)庫(kù),提供和C語(yǔ)言兼容的數(shù)據(jù)類(lèi)型,可以直接調(diào)用動(dòng)態(tài)鏈接庫(kù)中的導(dǎo)出函數(shù)。

為了使用ctypes,必須依次完成以下步驟:

·加載動(dòng)態(tài)鏈接庫(kù)

·將python對(duì)象轉(zhuǎn)換成ctypes所能識(shí)別的參數(shù)

·使用ctypes所能識(shí)別的參數(shù)調(diào)用動(dòng)態(tài)鏈接庫(kù)中的函數(shù)

動(dòng)態(tài)鏈接庫(kù)加載方式有三種:

·cdll

·windll

·oledll

它們的不同之處在于:動(dòng)態(tài)鏈接庫(kù)中的函數(shù)所遵守的函數(shù)調(diào)用方式(calling convention)以及返回方式有所不同。

cdll用于加載遵循cdecl調(diào)用約定的動(dòng)態(tài)鏈接庫(kù),windll用于加載遵循stdcall調(diào)用約定的動(dòng)態(tài)鏈接庫(kù),oledll與windll完全相同,只是會(huì)默認(rèn)其載入的函數(shù)統(tǒng)一返回一個(gè)Windows HRESULT錯(cuò)誤編碼。

函數(shù)調(diào)用約定:函數(shù)調(diào)用約定指的是函數(shù)參數(shù)入棧的順序、哪些參數(shù)入棧、哪些通過(guò)寄存器傳值、函數(shù)返回時(shí)棧幀的回收方式
(是由調(diào)用者負(fù)責(zé)清理,還是被調(diào)用者清理)、函數(shù)名稱(chēng)的修飾方法等等。常見(jiàn)的調(diào)用約定有cdecl和stdcall兩種。
在《程序員的自我修養(yǎng)--鏈接、裝載與庫(kù)》一書(shū)的第10章有對(duì)函數(shù)調(diào)用約定的更詳細(xì)介紹。  
cdecl規(guī)定函數(shù)參數(shù)列表以從右到左的方式入棧,且由函數(shù)的調(diào)用者負(fù)責(zé)清除棧幀上的參數(shù)。stdcall的參數(shù)入棧方式與cdecl一致,
但函數(shù)返回時(shí)是由被調(diào)用者自己負(fù)責(zé)清理?xiàng)?。而且stdcall是Win32 API函數(shù)所使用的調(diào)用約定。

例子:

Linux下:

python ctypes的作用有哪些

或者:

python ctypes的作用有哪些

其他例子:

python ctypes的作用有哪些

一個(gè)完整的例子:

1.編寫(xiě)動(dòng)態(tài)鏈接庫(kù)

// filename: foo.c
#include "stdio.h"
char* myprint(char *str)
{
    puts(str);
    return str;
}
float add(float a, float b)
{
    return a + b;
}

將foo.c編譯為動(dòng)態(tài)鏈接庫(kù):

gcc -fPIC -shared foo.c -o foo.so

2.使用ctypes調(diào)用foo.so

#coding:utf8
#FILENAME:foo.py
from ctypes import *
foo = CDLL('./foo.so')
myprint = foo.myprint
myprint.argtypes = [POINTER(c_char)] # 參數(shù)類(lèi)型為char指針
myprint.restype = c_char_p # 返回類(lèi)型為char指針
res = myprint('hello ctypes')
print(res)
add = foo.add
add.argtypes = [c_float, c_float] # 參數(shù)類(lèi)型為兩個(gè)float
add.restype = c_float # 返回類(lèi)型為float
print(add(1.3, 1.2))

執(zhí)行:

[jingjiang@iZ255w0dc5eZ test]$ python2.6 foo.py 
hello ctypes
hello ctypes
2.5

ctypes數(shù)據(jù)類(lèi)型和C數(shù)據(jù)類(lèi)型對(duì)照表

python ctypes的作用有哪些

查找動(dòng)態(tài)鏈接庫(kù)

>>> from ctypes.util import find_library
>>> find_library("m")
'libm.so.6'
>>> find_library("c")
'libc.so.6'
>>> find_library("bz2")
'libbz2.so.1.0'

函數(shù)返回類(lèi)型

函數(shù)默認(rèn)返回 C int 類(lèi)型,如果需要返回其他類(lèi)型,需要設(shè)置函數(shù)的 restype 屬性。

>>> from ctypes import *
>>> from ctypes.util import find_library
>>> libc = cdll.LoadLibrary(find_library("c"))
>>> strchr = libc.strchr
>>> strchr("abcdef", ord("d"))
-808023673
>>> strchr.restype = c_char_p
>>> strchr("abcdef", ord("d"))
'def'
>>> strchr("abcdef", ord("x"))

回調(diào)函數(shù)

·定義回調(diào)函數(shù)類(lèi)型,類(lèi)似于c中的函數(shù)指針,比如:void (*callback)(void* arg1, void* arg2),定義為:callack = CFUNCTYPE(None, cvoidp, cvoidp)

None表示返回值是void,也可以是其他類(lèi)型。剩余的兩個(gè)參數(shù)與c中的回調(diào)參數(shù)一致。

·定義python回調(diào)函數(shù):

def _callback(arg1, arg2):
    #do sth
    # ...
    #return sth

·注冊(cè)回調(diào)函數(shù):

cb = callback(_callback)

另外,使用ctypes可以避免GIL的問(wèn)題。

一個(gè)例子:

//callback.c
#include "stdio.h"
void showNumber(int n, void (*print)())
{
    (*print)(n);
}

編譯成動(dòng)態(tài)鏈接庫(kù):

gcc -fPIC -shared -o callback.so callback.c

編寫(xiě)測(cè)試代碼:

#FILENAME:callback.py
from ctypes import *
_cb = CFUNCTYPE(None, c_int)
def pr(n):
    print 'this is : %d' % n 
cb = _cb(pr)
callback = CDLL("./callback.so")
showNumber = callback.showNumber
showNumber.argtypes = [c_int, c_void_p]
showNumber.restype = c_void_p
for i in range(10):
    showNumber(i, cb)

執(zhí)行:

$ python2.7 callback.py 
this is : 0 
this is : 1 
this is : 2 
this is : 3 
this is : 4 
this is : 5 
this is : 6 
this is : 7 
this is : 8 
this is : 9

 結(jié)構(gòu)體和聯(lián)合

union(聯(lián)合體 共用體)
1、union中可以定義多個(gè)成員,union的大小由最大的成員的大小決定。 
2、union成員共享同一塊大小的內(nèi)存,一次只能使用其中的一個(gè)成員。 
3、對(duì)某一個(gè)成員賦值,會(huì)覆蓋其他成員的值(也不奇怪,因?yàn)樗麄児蚕硪粔K內(nèi)存。但前提是成員所占字節(jié)數(shù)相同,
當(dāng)成員所占字節(jié)數(shù)不同時(shí)只會(huì)覆蓋相應(yīng)字節(jié)上的值,>比如對(duì)char成員賦值就不會(huì)把整個(gè)int成員覆蓋掉,因?yàn)閏har只占一個(gè)字節(jié),
而int占四個(gè)字節(jié))
4、聯(lián)合體union的存放順序是所有成員都從低地址開(kāi)始存放的。

結(jié)構(gòu)體和聯(lián)合必須從Structure和Union繼承,子類(lèi)必須定義__fields__屬性,__fields__屬性必須是一個(gè)二元組的列表,包含field的名稱(chēng)和field的類(lèi)型,field類(lèi)型必須是一個(gè)ctypes的類(lèi)型,例如:c_int, 或者其他繼承自ctypes的類(lèi)型,例如:結(jié)構(gòu)體,聯(lián)合,數(shù)組,指針。

from ctypes import *
class Point(Structure):
    __fields__ = [         ("x", c_int),
        ("y", c_int),
    ]   
    def __str__(self):
        return "x={0.x}, y={0.y}".format(self)
point1 = Point(x=10, y=20)
print "point1:", point1
class Rect(Structure):
    __fields__ = [ 
        ("upperleft", Point),
        ("lowerright", Point),
    ]   
    def __str__(self):
        return "upperleft:[{0.upperleft}], lowerright:[{0.lowerright}]".format(self)
rect1 = Rect(upperleft=Point(x=1, y=2), lowerright=Point(x=3, y=4))
print "rect1:", rect1

運(yùn)行:

python test.py 
point1: x=10, y=20
rect1: upperleft:[x=1, y=2], lowerright:[x=3, y=4]

數(shù)組

數(shù)組定義很簡(jiǎn)單,比如:定義一個(gè)有10個(gè)Point元素的數(shù)組,

TenPointsArrayType = Point * 10。

初始化和使用數(shù)組:

from ctypes import *
TenIntegersArrayType = c_int * 10
array1 = TenIntegersArrayType(*range(1, 11))print array1
for i in array1:
    print i

運(yùn)行:

$ python2.7 array.py
<__main__.c_int_Array_10 object at 0x7fad0d7394d0>
1
2
3
4
5
6
7
8
9
10

指針

pointer()可以創(chuàng)建一個(gè)指針,Pointer實(shí)例有一個(gè)contents屬性,返回指針指向的內(nèi)容。

>>> from ctypes import *
>>> i = c_int(42)
>>> p = pointer(i)
>>> p<__main__.LP_c_int object at 0x7f413081d560>
>>> p.contents
c_int(42)
>>>

可以改變指針指向的內(nèi)容

>>> i = c_int(99)
>>> p.contents = i
>>> p.contents
c_int(99)

可以按數(shù)組的方式訪(fǎng)問(wèn),并改變值

>>> p[0]
99
>>> p[0] = 22
>>> i
c_int(22)

傳遞指針或引用

很多情況下,c函數(shù)需要傳遞指針或引用,ctypes也完美支持這一點(diǎn)。

byref()用來(lái)傳遞引用參數(shù),pointer()也可以完成同樣的工作,但是pointer會(huì)創(chuàng)建一個(gè)實(shí)際的指針對(duì)象,如果你不需要一個(gè)指針對(duì)象,用byref()會(huì)快很多。

>>> from ctypes import *
>>> i = c_int()
>>> f = c_float()
>>> s = create_string_buffer('\000' * 32) >>> print i.value, f.value, repr(s.value)
0 0.0 ''
>>> libc = CDLL("libc.so.6")
>>> libc.sscanf("1 3.14 Hello", "%d %f %s", byref(i), byref(f), s)
3   
>>> print i.value, f.value, repr(s.value)
1 3.1400001049 'Hello'

可改變內(nèi)容的字符串

如果需要可改變內(nèi)容的字符串,需要使用 createstringbuffer()

>>> from ctypes import *
>>> p = create_string_buffer(3)      # create a 3 byte buffer,  initialized to NUL bytes
>>> print sizeof(p), repr(p.raw)
3 '/x00/x00/x00'>>> p = create_string_buffer("Hello")      # create a buffer containing a NUL terminated string
>>> print sizeof(p), repr(p.raw)
6 'Hello/x00'
>>> print repr(p.value)
'Hello'
>>> p = create_string_buffer("Hello", 10)  # create a 10 byte buffer
>>> print sizeof(p), repr(p.raw)
10 'Hello/x00/x00/x00/x00/x00'
>>> p.value = "Hi"
>>> print sizeof(p), repr(p.raw)
10 'Hi/x00lo/x00/x00/x00/x00/x00'
>>>

賦值給c_char_p,c_wchar_p,c_void_p

只改變他們指向的內(nèi)存地址,而不是改變內(nèi)存的內(nèi)容

>>> s = "Hello, World"
>>> c_s = c_char_p(s)
>>> print c_s
c_char_p('Hello, World')>>> c_s.value = "Hi, there"
>>> print c_s
c_char_p('Hi, there')
>>> print s                 # first string is unchanged
Hello, World
>>>

數(shù)據(jù)都可以改變

>>> i = c_int(42)
>>> print i
c_long(42)
>>> print i.value42
>>> i.value = -99
>>> print i.value
-99
>>>

關(guān)于python ctypes的作用有哪些就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到。

當(dāng)前文章:pythonctypes的作用有哪些
網(wǎng)頁(yè)路徑:http://chinadenli.net/article33/gdodss.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、定制網(wǎng)站、手機(jī)網(wǎng)站建設(shè)、商城網(wǎng)站網(wǎng)站改版、網(wǎng)頁(yè)設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)
亚洲天堂一区在线播放| 欧美一级片日韩一级片| 国产熟女一区二区三区四区| 亚洲欧美日韩网友自拍| 精品国产丝袜一区二区| 中文字幕中文字幕在线十八区| 久久国产精品热爱视频| 亚洲中文字幕在线观看四区 | 国产精品久久熟女吞精| 久久精品色妇熟妇丰满人妻91 | 精品国自产拍天天青青草原| 午夜亚洲精品理论片在线观看| 亚洲国产av精品一区二区| 日韩18一区二区三区| 国产亚洲系列91精品| 久久99精品国产麻豆婷婷洗澡| 国产亚洲午夜高清国产拍精品| 亚洲一区二区三区三区| 福利在线午夜绝顶三级| 富婆又大又白又丰满又紧又硬 | 国产爆操白丝美女在线观看| 日韩一本不卡在线观看| 中文字幕亚洲精品人妻| 亚洲精品国男人在线视频| 少妇人妻中出中文字幕| 欧美成人黄色一级视频| 在线欧洲免费无线码二区免费| 99免费人成看国产片| 国产主播精品福利午夜二区| 国产精品一区二区三区激情| 精品国产亚洲av久一区二区三区| 中文字幕一二区在线观看| 精品国产一区二区欧美| 日本福利写真在线观看| 中文字幕一二区在线观看| 久久中文字幕中文字幕中文| 国产欧美日韩一级小黄片| 国产二级一级内射视频播放| 亚洲欧美日韩熟女第一页| 久久中文字人妻熟女小妇| 精品精品国产欧美在线|