Python ctypes behaviour with variable types

Tags: , ,



I’m using a third party python library, that is using ctypes (it uses a dll). I’m not very familiar with ctypes. The lib offers a type definition and a structure definition as given in the minimum example below. I’m trying to assign the member variable myClassInst.MSGTYPE the value of the constant MYConst. Afterwards I want to check the value with the unittest assertion macro but check fails due to different types. The different types are shown in the output below, too.

I do not understand, why the types differ? What’s the correct way to write that piece of code? I’m quite new to Python, so thank you in advance for your support

from ctypes import *
import unittest

MyType  = c_ubyte
MYConst = MyType(0xED)

class MyClass (Structure):
    _fields_ = [ ("MSGTYPE", MyType) ]

class myTest(unittest.TestCase):
    def test(self):
        myClassInst = MyClass()
        myClassInst.MSGTYPE = MYConst
        print(type(MYConst))
        print(type(myClassInst.MSGTYPE))
        self.assertEqual(MYConst, myClassInst.MSGTYPE)

if __name__ == '__main__':
    unittest.main()

The output is:

<class 'ctypes.c_ubyte'>
<class 'int'>
F
======================================================================
FAIL: test (__main__.myTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "mimimumexample.py", line 16, in test
    self.assertEqual(MYConst, myClassInst.MSGTYPE)
AssertionError: c_ubyte(237) != 237

----------------------------------------------------------------------
Ran 1 test in 0.002s

FAILED (failures=1)

Answer

In a ctypes structure, ctypes “helpfully” converts to/from Python objects when reading/writing the member variables, so reading MYConst produces a Python int.

Change MYConst = MyType(0xED) to MyConst = 0xED and it will work correctly.

(and THANK YOU for a standalone example with unit test!)



Source: stackoverflow