如何从导入的成员函数中获取对象?

时间:2013-01-08 15:15:39

标签: python ctypes member

在下面的代码示例中,我希望能够在帮助函数中使用dll对象。

def HelperFunc():
    # How to use dll here?
    pass

def LoadMyDLL():
    dll = ctypes.CDLL( "libmydll.so" )
    dll.HelperFunction = HelperFunction
    return dll

dll = LoadMyDLL()
dll.HelperFunc()

我显然可以将它作为参数传递给HelperFunc,但是我正在导入这个函数,假装它被包含在dll中,用dll.HelperFunc(dll)调用它是不干净的dll重复。

我还可以将dll对象存储到全局变量中。然后,我需要添加一个保护,以避免加载dll两次,保持一个dll加载。

但是有没有办法从dll中获取HelperFunc,或者让它以默默方式传递?

3 个答案:

答案 0 :(得分:2)

为避免全局变量,您可以使用闭包或使用静态方法的对象来保存和重用dll。

def LoadMyDLL(dll = ctypes.CDLL( "libmydll.so" )):
    def closure():
        return dll
    return closure

dll = LoadMyDLL()()

和helper func一样使用dll绑定:

def HelperFunc():
    dll = LoadMyDLL()()
    # and use the dll

<强>更新

上面的答案有效,不是因为闭包,而是因为全局函数LoadMyDLL中的default关键字参数dll。

当函数LoadMyDLL被定义为全局函数时,此默认关键字参数(dll = ...)被初始化一次。 这意味着有一个非常简单的解决方案:

def LoadMyDLL(dll = ctypes.CDLL( "libmydll.so" )):
    return dll

dll = LoadMyDLL() # get the dll, which has already been initialized 

并在辅助函数中:

def HelperFunc():
    dll = LoadMyDLL() # get the dll again
    # and use the same dll

答案 1 :(得分:1)

人们经常忘记(或永远不会学习)的一件事是,功能也具有属性,而且它们完全可变。所以你可以这样做:

def LoadMyDLL():
    dll = ctypes.CDLL("libmydll.so")
    dll.HelperFunction = HelperFunction
    dll.HelperFunction.dll = dll
    return dll

但是这会产生一个问题:dll.HelperFunction.dll is HelperFunction.dll。因此,无论您对LoadMyDLL的最后一次调用是什么,都将是附加到CDLL的{​​{1}}对象。如果您未在HelperFunction的上下文之外使用HelperFunction,我建议您执行以下操作:不要将dll.HelperFunction()设为HelperFunc的属性,只需调用dll需要。如果您希望它修改HelperFunction(dll),因为Python是通过引用传递的,它将会这样做。如果您不相信我并希望我发布示例代码,我很乐意用插图编辑它。

免责声明一般来说,您似乎在做什么对我来说看起来并不正确。如果你想做这样的事情,我建议你创建一个类,将dll对象存储为CDLL,并在类上创建self.dll方法。然后,您可以从该方法访问HelperFunction。当然,设计是你的决定,我看不到剩下的代码,但后者对我来说似乎更自然(我的猜测也是,对很多其他代码也是如此)。

编辑由于下面的讨论,我想知道如何构建我建议的类(即使上面的内容被接受)。< / p>

self.dll

答案 2 :(得分:1)

def HelperFunc():
    HelperFunc.dll.OtherFunction()

def LoadMyDLL():
    dll = ctypes.CDLL( "libmydll.so" )
    HelperFunction.dll = dll
    dll.HelperFunction = HelperFunc
    return dll

dll = LoadMyDLL()
dll.HelperFunc()

将是一种方法。肯定有更好的方法,但是......