user422005
user422005

Reputation: 2041

Calling C function from ctypes: class instance can be None

I have a C library with several datatypes which I have wrapped with Python and ctypes - works very well! In C I have the following (schematic) code:

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 {  
     // 
  }
}  

The main point in this code is that some_function() can take NULL as value for the t2 argument. In Python the type1_t and type2_t types are wrapped with classes Type1 and Type2 using the from_param() method:

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]

So the cfunc_some_function function is initialized to take a Type1 and Type2 instance as arguments, the ctypes layer will then call the from_param() methods of the two input arguments; however I would like the 'call_some_func()' method of the Type1 class to accept None for the arg2 argument, but then ctypes tries to call the from_param() method of the None object - which obviously fails.

So - I guess my question is: Is it possible to get the ctypes function call code to just pass NULL when it gets a None input argument?

Joakim

Upvotes: 1

Views: 1514

Answers (2)

Duncan
Duncan

Reputation: 95732

The from_param() method needs to be a class method, but you have defined it as an instance method. Change it to a classmethod and check whether the parameter is None.

Something like (untested):

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

and the same for Type2.

Upvotes: 3

HYRY
HYRY

Reputation: 97331

Maybe you can convert None to Type2 before call:

cfunc_some_function( self , Type2(arg2) )  

and Type2.from_param() returns the right object for cfunc_some_function().

Upvotes: 0

Related Questions