Python Cookbook(第3版)中文版:15.12 將函數指標轉換為可調用對象

來源:互聯網
上載者:User

標籤:htm   amp   app   targe   函數   是你   lvm   header   call   

15.12 將函數指標轉換為可調用對象?問題?

你已經獲得了一個被編譯函數的記憶體位址,想將它轉換成一個Python可調用對象,
這樣的話你就可以將它作為一個擴充函數使用了。

解決方案?

ctypes 模組可被用來建立封裝任意記憶體位址的Python可調用對象。
下面的例子示範了怎樣擷取C函數的原始、底層地址,以及如何將其轉換為一個可調用對象:

>>> import ctypes>>> lib = ctypes.cdll.LoadLibrary(None)>>> # Get the address of sin() from the C math library>>> addr = ctypes.cast(lib.sin, ctypes.c_void_p).value>>> addr140735505915760>>> # Turn the address into a callable function>>> functype = ctypes.CFUNCTYPE(ctypes.c_double, ctypes.c_double)>>> func = functype(addr)>>> func<CFunctionType object at 0x1006816d0>>>> # Call the resulting function>>> func(2)0.9092974268256817>>> func(0)0.0>>>
討論?

要構建一個可調用對象,你首先需要建立一個 CFUNCTYPE 執行個體。
CFUNCTYPE() 的第一個參數是傳回型別。
接下來的參數是參數類型。一旦你定義了函數類型,你就能將它封裝在一個整型記憶體位址上來建立一個可調用對象了。
產生的對象被當做普通的可通過 ctypes 訪問的函數來使用。

本節看上去可能有點神秘,偏底層一點。
但是,但是它被廣泛使用於各種進階代碼產生技術比如即時編譯,在LLVM函數庫中可以看到。

例如,下面是一個使用 llvmpy 擴充的簡單例子,用來構建一個小的聚集合函式,擷取它的函數指標,
並將其轉換為一個Python可調用對象。

>>> from llvm.core import Module, Function, Type, Builder>>> mod = Module.new(‘example‘)>>> f = Function.new(mod,Type.function(Type.double(),                      [Type.double(), Type.double()], False), ‘foo‘)>>> block = f.append_basic_block(‘entry‘)>>> builder = Builder.new(block)>>> x2 = builder.fmul(f.args[0],f.args[0])>>> y2 = builder.fmul(f.args[1],f.args[1])>>> r = builder.fadd(x2,y2)>>> builder.ret(r)<llvm.core.Instruction object at 0x10078e990>>>> from llvm.ee import ExecutionEngine>>> engine = ExecutionEngine.new(mod)>>> ptr = engine.get_pointer_to_function(f)>>> ptr4325863440>>> foo = ctypes.CFUNCTYPE(ctypes.c_double, ctypes.c_double, ctypes.c_double)(ptr)>>> # Call the resulting function>>> foo(2,3)13.0>>> foo(4,5)41.0>>> foo(1,2)5.0>>>

並不是說在這個層面犯了任何錯誤就會導致Python解譯器掛掉。
要記得的是你是在直接跟機器層級的記憶體位址和本地機器碼打交道,而不是Python函數。

艾伯特(http://www.aibbt.com/)國內第一家人工智慧門戶

Python Cookbook(第3版)中文版:15.12 將函數指標轉換為可調用對象

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

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.