Open In App

Issues with using C code in Python | Set 2

Last Updated : 20 Mar, 2019
Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisite: Issues with using C code in Python | Set 1

The DoubleArrayType class can handle the situation of Python having different forms like array, numpy array, list, tuple. In this class, a single method from_param() is defined. This method takes a single parameter and narrow it down to a compatible ctypes object (a pointer to a ctypes.c_double, in the example).

In the code below, the typename of the parameter is extracted and used to dispatch to a more specialized method. For example, if a list is passed, the typename is list and a method from_list() is invoked. For lists and tuples, the from_list() method performs a conversion to a ctypes array object.

Code #1 :




nums = [1, 2, 3]
a = (ctypes.c_double * len(nums))(*nums)
print ("a : ", a)
  
print ("\na[0] : ", a[0])
  
print ("\na[1] : ", a[1])
  
print ("\na[2] : ", a[2])


Output :

a : <__main__.c_double_Array_3 object at 0x10069cd40>

a[0] : 1.0

a[1] : 2.0

a[2] : 3.0

 
The from_array() method extracts the underlying memory pointer and casts it to a ctypes pointer object for array objects.

Code #2 :




import array
arr = array.array('d', [1, 2, 3])
print ("arr : ", arr)
  
ptr_ = a.buffer_info()
print ("\nptr :", ptr)
  
print ("\n", ctypes.cast(ptr, ctypes.POINTER(ctypes.c_double)))


Output :

arr : array('d', [1.0, 2.0, 3.0])

ptr : 4298687200

<__main__.LP_c_double object at 0x10069cd40> 

 
The from_ndarray() shows comparable conversion code for numpy arrays. By defining the DoubleArrayType class and using it in the type signature of avg(), the function can accept a variety of different array-like inputs.

Code #3 :




# libraries
import sample
import array
import numpy
  
print("Average of list : ", sample.avg([1, 2, 3]))
  
print("\nAverage of tuple : ", sample.avg((1, 2, 3)))
  
print(\nAverage of array : ", sample.avg(array.array('d', [1, 2, 3])))
  
print(\nAverage of numpy array : ", sample.avg(numpy.array([1.0, 2.0, 3.0])))


Output :

Average of list : 2.0

Average of tuple : 2.0 

Average of array : 2.0

Average of numpy array : 2.0

 
To work with a simple C structure, simply define a class that contains the appropriate fields and types as shown in the code below. After defining, the class in type signatures as well as in code that needs to instantiate and work with the structures, can be used.

Code #4 :




class Point(ctypes.Structure):
    _fields_ = [('x', ctypes.c_double),
                ('y', ctypes.c_double)]
  
point1 = sample.Point(1, 2)
point2 = sample.Point(4, 5)
  
print ("pt1 x : ", point1.x)
  
print ("\npt1 y : ", point1.y)
  
print ("\nDistance between pt1 and pt2 : ",
           sample.distance(point1, point2))


Output :

pt1 x : 1.0

pt1 y : 2.0

Distance between pt1 and pt2 : 4.242640687119285


Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads