将Python对象传递给C模块

时间:2014-12-27 00:06:31

标签: python ctypes

说我有这个简单的类和实例:

class MyClass:
    def __init__(self, value):
        self.value = value

    def my_method(self):
        return self.value * 2

my_object = MyClass(1)

是否可以使用my_object或任何其他模块将ctypes直接传递给C?如果我能够在C中至少获得my_object的属性,我会很高兴,但更好。如果我能够获得方法并且能够在C中调用它们。

我现在正在做:

import ctypes
my_library = ctypes.CDLL('my_library.so')
my_library.my_c_function.argtypes = [ctypes.c_int]
my_library.my_c_function.restype = ctypes.c_int

my_object_c_value = ctypes.c_int(my_object.value)
my_library.my_c_function(my_object_c_value)

为my_object中的每个属性执行此操作。当类具有太多属性时,这会非常重复。

我尝试阅读关于ctypes的文档,但它太技术化了,对我来说不太全意。

1 个答案:

答案 0 :(得分:1)

不,你不能以这种方式将纯Python对象传递给C.但是,您可以声明一个ctypes.Structure或ctypes.Union类型并将其传递给c函数,就像它是一个C结构或联合一样,通常带有一个POINTER。

文档示例:

from ctypes import *
class POINT(Structure):
    _fields_ = [("x", c_int),
                ("y", c_int)]

point = POINT(10, 20)
...
my_library.my_c_function(POINTER(point))

但是,从您的示例中,您只是传递一个整数。 ctypes模块知道如何在没有这种声明的情况下映射该类型。

您不必申报所有类型。这更适用于调试和自动类型转换。您可以在创建库后立即调用您的函数:

my_library = ctypes.CDLL('my_library.so')
my_library.my_c_function(...)

但是,调试声明你需要的是一个好主意。编写一个小型Python程序并将其转换为一组类似的声明并不困难。我曾经一直以这种方式加载平台包含文件。我喜欢ctypes并且一直使用它,但是如果你想要更简短的东西,也许你会喜欢" cython"更好?