Python Ctypes memory allocation for c function
<p>I currently have a python callback function that calls a c function using ctypes library. The c function requires a pointer to a structure for example animal_info_s. I instantiate the structure and pass it as a pointer to the c function and it works. The issue I'm having is when I have multiple threads calling the callback, I'm finding the information being passed back is mixed up between the threads. </p>

<pre><code>class animal_info_s(ctypes.Structure):
    _fields_ = [('dog_type',          ctypes.c_uint16),
                ('cat_type',          ctypes.c_uint16),
                ('bird_type',         ctypes.c_uint16),
                ('epoch_time',        ctypes.c_uint16),
                ('more_information',  ctypes.c_uint16)]


_mod = ctypes.cdll.LoadLibrary('bbuintflib.dll')
animal_info_s = animal_info_s()
get_animal_data = _mod.get_animal_data
get_animal_data.argtypes = [ctypes.POINTER(animal_info_s)]
get_animal_data.restype =   ctypes.c_int

# Python Callback
def GetAnimalData():
    animal_info_p = animal_info_s
    res = get_animal_data(animal_info_p)
    if (res != 0):
        print("Failed to get animal info")
        return

    print ("Receive Time - %d\nDog: %d\nCat: %d\nBird:%d" %(animal_info_p.epoch_time,
                                                            animal_info_p.dog_type,
                                                            animal_info_p.cat_type,
                                                            animal_info_p.bird_type))
</code></pre>

<p>I think what is happening is when I instantiate the structure, it is using the same memory location every time. How do I create a new memory location for each thread calling the callback?</p>

<p>The following line should be removed.  It redefines the name <code>animal_info_s</code>  as a <code>class animal_info_s</code> instance, which then hides the class.</p>

<pre><code>animal_info_s = animal_info_s()
</code></pre>

<p>The following line should be changed from:</p>

<pre><code>animal_info_p = animal_info_s
</code></pre>

<p>to:</p>

<pre><code>animal_info_p = animal_info_s()
</code></pre>

<p>The original line made another name for the <code>animal_info_s</code> name from the first error, which was the one-and-only instance used in the threads.  the recommended line creates a new instance of the <code>animal_info_s</code> class each time the callback is called.</p>

python memory-management ctypes