2014-08-27 66 views
2

我想在Python中使用SSL庫,我需要編寫一個C++代碼的克隆代碼。通過引用或等效Python調用

在C SSL函數被調用是這樣的:

EVP_MD_CTX mdctx; 
EVP_MD_CTX_init(&mdctx) 

在Python我到達SSL庫:

import ctypes 
import ctypes.util 
import platform 
from os import linesep 

libraries = {} 

libraries["c"] = ctypes.CDLL(ctypes.util.find_library("c")) 

if platform.system() != "Windows": 
    libraries["ssl"] = ctypes.CDLL(ctypes.util.find_library("ssl")) 
else: 
    libraries["ssl"] = ctypes.CDLL(ctypes.util.find_library("libeay32")) 

EVP_MD_CTX_init = libraries['ssl'].EVP_MD_CTX_init 
EVP_MD_CTX_init.restype = ctypes.c_void_p 
EVP_MD_CTX_init.argtypes = [ctypes.c_void_p] 

這是從here

採取怎樣可以我擦肩而過EVP_MD_CTX_init功能它是用C編寫的嗎? 由於我不得不EVP_MD_CTX_init()method.I沒有訪問具有「通過引用通」

我試圖EVP_MD_CTX_init(ctypes.byref(mdctx)),但語法錯誤調用此方法是用occured.Is有任何方式做這個?

+0

我重新打開了你的問題,因爲我雖然你問的是不是真正的副本[其他問題](http://stackoverflow.com/questions/7530473/ctypes-and-passing-a-by-reference -to-A-功能?LQ = 1)。然後你編輯了這個問題以刪除所有相關的內容,所以實際上仍然是重複的。你爲什麼這麼做? – abarnert 2014-08-27 11:24:37

+0

更重要的一點:你問如何按引用傳遞'ctypes'值C函數,如何通過引用傳遞'ctypes'值Python函數,或者只是如何變異在Python'ctypes'值?它們都是不同的東西,如果你要求其中一個答案,它不會幫助你做其他答案。 – abarnert 2014-08-27 11:25:16

+0

如果您希望我們調試代碼,你必須向我們展示的代碼,你得到的錯誤,不只是含糊地描述你嘗試和發生了什麼事。有一個在表達'EVP_MD_CTX_init(ctypes.byref(mdctx))'沒有語法錯誤,那麼很可能是你嘗試了一些_other_問題,但沒有看到它,我甚至不能開始猜測。這可能是一個缺少')'前行,一個流浪非ASCII字符,或一個百萬的東西。 – abarnert 2014-08-27 12:06:27

回答

2

您應該諮詢ctypes documentation

要走的路是使用​​模塊導出的byref()pointer()(更慢,更復雜)功能,如示例中所示。

>>> print ctypes.byref.__doc__ 
byref(C instance[, offset=0]) -> byref-object 
Return a pointer lookalike to a C instance, only usable 
as function argument 
2

這在​​文檔進行了說明,在Passing pointers (or: passing by reference)

有時C API函數需要一個指向一個數據類型作爲參數,可能要寫入到相應的位置,或者如果數據太大而無法通過值傳遞。這也被稱爲通過引用傳遞參數。

ctypes導出用於通過引用傳遞參數的byref()函數。同樣的效果可以用pointer()功能來實現,雖然pointer()做了很多工作,因爲它初始化了一個指針對象,因此它是更快地使用byref(),如果你不需要在Python本身的指針對象:

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

但是,現在你所提供的代碼,你不是試圖把它傳遞給C函數需要一個指針,你試圖將它傳遞給一個Python功能。

如果您想這樣做,如文檔解釋,您需要使用pointer而不是byref。當然,Python函數需要期望POINTER(c_int)而不是c_int

但是,在這方面,你甚至沒有這樣做。你已經寫下了這段代碼:

a=ctypes.c_int(35) 

def foo(n): 
    n=ctypes.c_int(19) 

你沒有對傳入的值做任何事情;你只是將當地名稱n重新綁定到不同的新建值。

所有你需要做的就是改變值:

def foo(n): 
    n.value = 19 

那麼就沒有必要爲byref或這裏pointer

+0

它沒有幫助,因爲我想用它作爲函數/方法的paremeter。 – Bhoke 2014-08-27 11:00:01

+0

@Boke:看我編輯的答案。但是,既然你已經重新編輯了這個問題,我不確定我瞭解你的問題了。 – abarnert 2014-08-27 11:25:49

+0

我再次編輯它,我認爲現在很清楚。謝謝 – Bhoke 2014-08-27 11:57:40