Python引用或等效的调用

时间:2014-08-27 08:48:37

标签: python c ssl pass-by-reference

我正在尝试在Python中使用SSL库,我需要编写C ++代码的克隆代码。

在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()方法。我必须通过引用传递此方法'

我尝试了EVP_MD_CTX_init(ctypes.byref(mdctx)),但发生了语法错误。有什么方法可以做到这一点吗?

2 个答案:

答案 0 :(得分:2)

您应该参考ctypes documentation

可行的方法是使用byref()模块导出的pointer()ctypes(更慢和更复杂)函数,如示例所示。

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

答案 1 :(得分:2)

Passing pointers (or: passing by reference)中的ctypes文档对此进行了解释:

  

有时,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

然后,此处不需要byrefpointer