简体   繁体   English

在 Python 中为面向对象编程包装 C

[英]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.我编写了一个C代码,用于与 Raspberry Pi 进行芯片通信,其中包括几个公共功能。

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.为了包装它以在Python使用,我将代码编译到so文件中并使用了ctypes ,因为这对我来说是最简单的方法。

However, there are two flaws to this method:但是,这种方法有两个缺陷:

  1. Python code is sometimes rather quirky . Python 代码有时相当古怪 For example, if the function takes an array for the argument, coding in Python looks like this:例如,如果函数采用一个数组作为参数,Python 中的编码如下所示:
 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 .最后,我想将我的软件公开并发布到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 .我知道有包裹的许多其他方法C代码Python ,如所描述这里 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. C库中的函数可用于所有芯片,但每个芯片都需要在库中保存一组不同的变量。

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?在 Python 中定义类,其中创建新对象意味着在连接到该对象的库中创建新struct Or perhaps use new instance of C library for each object?或者也许为每个对象使用C库的新实例? Or perhaps create classes/objects within C library?或者在C库中创建类/对象? I am completely clueless.我完全一窍不通。

Presumably you're talking about the Microchip MCP4728.大概您在谈论 Microchip MCP4728。 This is an I2C attached device, and so it has an address on the I2C bus.这是一个 I2C 连接设备,因此它在 I2C 总线上有一个地址。 If you're using it in its default factory condition, address 0b1100000.如果您在默认出厂条件下使用它,请访问地址 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.因此,要拥有“两个不同的芯片”,您需要 2 个独立的 I2C 总线,或者利用 MCP4728 上的可重新编程寻址并将其中一个设置为 0b1100001(为此您需要控制 /LDAC 引脚在设备上),以便 2 个可以存在于一个 I2C 总线上。

Either way, you'll need some sort of "context" for the device that you can pass to your C functions.无论哪种方式,您都需要某种可以传递给 C 函数的设备的“上下文”。 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.您可以将此结构传递到每个 C 函数中,就像 OI Sen 所描述的那样。 MCP4728 上有各种可用设置(如 VRef 选择、增益和电源状态),因此将这些设置的当前值存储在结构中也是个好主意。

==EDIT== ==编辑==

Pygmalion (OP) has found a link to a useful answer, here Python ctypes pointer to struct as identifier without member access . Pygmalion (OP) 找到了一个有用答案的链接,这里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.此外,将整个内容包装在一个 python 类中可能会很方便,因此您可以使用__del__析构函数来确保自动进行清理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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