我正在尝试在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)),但发生了语法错误。有什么方法可以做到这一点吗?
答案 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
然后,此处不需要byref
或pointer
。