Issues with using C code in Python | Set 2

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 :

filter_none

edit
close

play_arrow

link
brightness_4
code

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])

chevron_right


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 :

filter_none

edit
close

play_arrow

link
brightness_4
code

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)))

chevron_right


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 :

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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])))

chevron_right


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 :

filter_none

edit
close

play_arrow

link
brightness_4
code

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))

chevron_right


Output :

pt1 x : 1.0

pt1 y : 2.0

Distance between pt1 and pt2 : 4.242640687119285


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.