简体   繁体   中英

Wrapping C for object oriented programming in Python

I have written a C code for chip communication with Raspberry Pi that includes several public functions.

To wrap it for use in Python I compiled the code into so file and used ctypes , because it was for me far the easiest way to do that.

However, there are two flaws to this method:

  1. Python code is sometimes rather quirky . For example, if the function takes an array for the argument, coding in Python looks like this:
 MCP4728 = cdll.LoadLibrary("./MCP4728.so") multipleexternal = MCP4728.multipleexternal multipleexternal.restype = c_int multipleexternal.argtypes = [POINTER(c_float), c_bool] voltages=[0.5,1.5,2.5,2.5] floats = (c_float*4)(*voltages) multipleinternal(floats,False)
  1. I do not know how to convert this for object oriented programming , so one can connect two different chips at the same time .

  2. Finally, I want to make my software public and post it on github . Maybe some other wrapping method is preferred in this case.

I am aware that there are many other methods of wrapping the C code for Python , as described here . Could you give me a suggestion which method to use and perhaps even a object oriented programming example that would be most appropriate?

Thanks for help!

EDIT:

This is not only a question of syntax but also of concepts . The functions in the C library could be used for all chips, but a different set of variables held within a library is necessary for each chip.

So what should I do? Define classes in Python, where creating a new object means creating new struct in the library connected to that object? Or perhaps use new instance of C library for each object? Or perhaps create classes/objects within C library? I am completely clueless.

Presumably you're talking about the Microchip MCP4728. This is an I2C attached device, and so it has an address on the I2C bus. If you're using it in its default factory condition, address 0b1100000. So, to have "two different chips", you'd need either 2 separate I2C buses, or take advantage of the reprogrammable addressing on the MCP4728 and set one of them to 0b1100001 (for which you'll need control of the /LDAC pin on the devices) so that 2 can exist on one I2C bus.

Either way, you'll need some sort of "context" for the device that you can pass to your C functions. That might simply be the bus number or the device address.

Or you could get creative and (as hinted at in the comments) have some sort of struct that, amongst other things, contains the device address or bus number. For that you'd need an initialiser, a function that'll act in an equivalent manner to a constructor. You'd pass this struct into each of the C functions, much as described by OI Sen. There's various settings available on the MCP4728 (like VRef selection, gain, and power state), so storing the current values of those in the struct would also be a good idea.

==EDIT==

Pygmalion (OP) has found a link to a useful answer, here Python ctypes pointer to struct as identifier without member access .

Also, it might be convenient to wrap the whole thing up in a python class, whereupon you could have a __del__ destructor to ensure that the cleanup happens automatically.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM