通过ctypes调用C函数时:类实例可以是None

1 投票
2 回答
1493 浏览
提问于 2025-04-16 23:11

我有一个C语言的库,里面有几种数据类型,我用Python和ctypes把它们封装起来了,效果很好!在C语言中,我有以下(示意)代码:

typedef struct type1_struct type1_t;
typedef struct type2_struct type2_t;  

void some_function( type1_t *t1 , type2_t *t2) {  
  if (t2 == NULL) {  
     // Do whatever  
  } else {  
     // 
  }
}  

这段代码的重点是,some_function()这个函数可以接受NULL作为t2参数的值。在Python中,type1_t和type2_t这两种类型被封装成了Type1和Type2类,并使用了from_param()方法:

Class Type1:
   def from_param(self):
       return self.c_ptr


   def call_some_func(self , arg2 = None):
       # This fails when the python/ctypes tries to
       # lookup the from_param() method and arg2 is None. 
       cfunc_some_function( self , arg2 )     


lib_handle = ctypes.CDLL( lib )
cfunc_some_function = getattr( lib_handle , "some_function")
cfunc_some_function.argtypes = [Type1 , Type2]

因此,cfunc_some_function函数被设置为接受Type1和Type2的实例作为参数,ctypes层会调用这两个输入参数的from_param()方法;但是我希望Type1类的'call_some_func()'方法能够接受None作为arg2参数,但ctypes却试图调用None对象的from_param()方法,这显然是失败的。

所以,我的问题是:有没有办法让ctypes在接收到None作为输入参数时,直接传递NULL?

Joakim

2 个回答

0

也许你可以在调用之前把 None 转换成 Type2:

cfunc_some_function( self , Type2(arg2) )  

而且 Type2.from_param() 会为 cfunc_some_function() 返回正确的对象。

3

这个 from_param() 方法应该是一个类方法,但你把它定义成了实例方法。把它改成 classmethod,并检查一下参数是否为 None。

可以像这样做(未测试):

class Type1:
   @classmethod
   def from_param(cls, obj):
       if obj is None:
           return c_void_p()
       else:
           return obj.c_ptr

Type2 也是一样的处理。

撰写回答