正在为现有库创建替代C API

ghhaqwfi  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(262)

在API中公开不同的类型名称而不使用库本身的类型是否被认为是一种不好的做法?
如果有这样的库:

struct Internal {
    int first;
    float second;
};

int foo(struct Internal);

typedef enum {
    VALUE_1,
    VALUE_2
} INTERNAL_ENUM;

int bar(INTERNAL_ENUM);

它可以与如下所示的标题链接:

struct External {
    int first;
    float second;
};

int foo(struct External);

typedef enum {
    VALUE_1,
    VALUE_2
} EXTERNAL_ENUM;

int bar(EXTERNAL_ENUM);

如果我创建的库使用了另一个库,并且我不希望公开该库,那么为API使用不同的类型名称是否被认为是不切实际的?
由于项目目前是建立的(我继承了它),有两组数据类型,一组由我维护,它镜像了一些内部(静态链接)库中使用的数据类型。代码更复杂,充满了bug,我想知道我的解决方案是否会更好?

7d7tgy0s

7d7tgy0s1#

如果我创建的库使用了另一个库,并且我不希望公开该库,那么为API使用不同的类型名称是否被认为是不切实际的?
“不切实际”就是一个词。
C语言的类型兼容规则要求结构类型不仅要有匹配的成员列表,而且要有匹配的标记或无标记匹配。联合和枚举也是如此。规则还要求同一对象或函数的所有声明都为其指定兼容的类型。*
这意味着,按照您所描述的那样做会引发未定义的行为。在这种情况下,这不仅包括未定义的运行时行为,还包括未定义的编译时行为。
给定

application ---uses---> library 1 ---uses---> library 2

你可以选择library 1的头是否将library 2的数据类型公开给application.如果你选择这样做,那么对于结构和联合类型,你也可以选择是否将它们公开为不透明类型.但是如果你想要良好定义的行为,那么你不能选择重新标记library 2的结构,联合,或枚举类型。不同的标记会产生不兼容的类型,正如C语言中使用的术语。
由于项目目前是建立的(我继承了它),有两组数据类型,一组由我维护,它镜像了一些内部(静态链接)库中使用的数据类型。代码更复杂,充满了bug,我想知道我的解决方案是否会更好?
我看不出您认为继续“镜像”内部库的数据类型(但使用不同的名称)会有什么好处。听起来这会在几个方面使您的问题更糟,而不是更好。
但是你绝对应该想出一种方法来避免重复的数据类型定义。安排一种或另一种方法,让所有涉及的翻译单元对所有使用的数据类型都使用 * 相同 * 的定义(或者根本不使用)。这就是头文件的用途。
当然,这是假设您要将对象从应用程序层通过库1传递到库2,这似乎就是您所描述的。这可能是一个好计划,但它不是您唯一的选择。

  • 这是关于类型本身的,而不是通过typedef声明的类型别名。

相关问题