【发布时间】:2014-07-25 01:37:10
【问题描述】:
我正在编写一些通过 python 的 ctypes 模块调用 C dll 的 python 代码。
有问题的 DLL 在其头文件中将一些返回值定义为 enums:
//
// Device status
//
enum {
FT_OK,
FT_INVALID_HANDLE,
FT_DEVICE_NOT_FOUND,
FT_DEVICE_NOT_OPENED,
FT_IO_ERROR,
FT_INSUFFICIENT_RESOURCES,
FT_INVALID_PARAMETER,
<continued---snip>
};
我是从 python 接口的,所以我没有原生枚举。我可以假设枚举的内容从0 的值开始,并为每个项目增加1吗?这很容易实现,但似乎我会依赖编译器的实现细节。
我已经对enum 变量的内部进行了一些挖掘,但我在内部找不到太多关于它们如何工作的信息。仅关于如何在 C/C#/whatever 中使用它们的文档。
我知道 enum 是否有各种变量的常量定义,我可以依赖它,但在这种情况下,我正在与我无权访问的外部代码交互(只是 dll) .
【问题讨论】:
-
下面的答案直接解决了您的问题。但是,对枚举值做出任何假设的弱点在于,如果源确实决定为这些枚举中的任何一个分配一个值,那么您所有的硬编码假设都会被取消。理想情况下,您应该包装枚举,以便您可以通过某种方式实际访问这些值,从而确保您始终进行预期的比较。
-
@aruisdante - 是的,这就是困扰我的问题。实际上,如果枚举被重组,它也会破坏很多其他人的代码(至少需要重新编译任何链接到 DLL 的东西),所以假设它不会改变可能是安全的。
-
一点也不。
enum的全部意义在于,只要您使用枚举,而不依赖于枚举的值,就应该始终没问题。对于大多数面向用户的代码来说,枚举的实际值是什么无关紧要。通过将枚举正确地视为特殊值而不是 int 构建的任何东西都可以工作。因此,实现者可以决定分配一个值,以便他们可以例如通过返回枚举从应用程序的退出值中获取描述性错误代码。 -
例如,如果我构建一个枚举来将索引表示为值数组,我可以任意更改这些索引处的值的位置,只要我更新枚举和所有代码建立在该枚举之上仍然可以正常工作。
-
@aruisdante - 我的观点是,如果 DLL 的枚举结构发生变化,任何与 DLL 接口的 c 代码都必须使用反映新枚举结构的头文件重新编译。您不需要更改用户代码,只需更改头文件,但您仍然需要重新编译,旧编译的代码无法链接新的dll。