【问题标题】:How to avoid function name conflict in a C library?如何避免 C 库中的函数名冲突?
【发布时间】:2021-04-15 12:14:18
【问题描述】:

我正在 Unix 上编写一个串行端口,我正在使用头文件 unistd.h。它包含功能:

read(int fd, void *buf, size_t count)

我正在创建一个类来调用这个函数,并且我的类中的一个方法也称为read() 来读取一个字符。但是当我编译时,它说它无法从unistd.h 中识别函数read()。如果我使用 C++,我可以添加 :: 来解决库冲突。使用 C++ 调用 C 库函数时如何解决库冲突?

以后当开发人员使用我的库时,它会变得简单整洁,如下所示:

Serial serial;
serial.read();

我的类名是Serial,包含方法read(),它本身从unistd.h调用函数read()

【问题讨论】:

  • 将 cpp 代码放在命名空间中,这样您就可以使用::function/my_namespace::function 来避免歧义。
  • ::read 有什么问题?
  • 如果 read 属于 Serial 类,并且 Serial::read call ::read 应该没问题,你的问题是什么?
  • @mpromonet Serial::read 从 unistd 调用 read()
  • serial.read(); 不是 C,除非 readSerial 结构中的函数指针。不要这样标记 C

标签: c++ name-lookup


【解决方案1】:

如果我使用的是 C++,我可以添加 :: 来解决库冲突。

但是您正在使用 C++。仅仅因为您包含包含 C API 的标头,并不意味着翻译单元不再是 C++ 翻译单元。如果标头被设计为与 C++ 配合使用,那么它的内容仍然放在全局命名空间中(并且 unistd.h 可以包含在 C++ 翻译单元中就好了)。

这意味着::read 将解析为unistd.h 声明的C 库函数。你可以在Serial::read 内很好地使用它。这些是 C++ 编译器的不同功能。只需在成员函数内消除名称的歧义,因为非限定名称查找必须在类范围内找到成员。

【讨论】:

  • 酷,我不知道你可以用这样的c函数添加::,谢谢
【解决方案2】:

当我使用 C++ 并从 C 调用函数时如何解决库冲突?

如果您编写 C++,通常会使用带有成员函数的类。并且编译器会看到调用与给定对象相关,因此您不会在冲突中运行。

如果你使用“免费函数”,你可以给这些函数一个自己的namespace,并简单地在调用中使用命名空间,比如serial::read();

您还可以向类添加静态函数,这将为它们提供一个命名范围,而无需从类本身创建对象。

namespace serial_ns
{
int read( int, void*, size_t n){return 0;}
}

struct serial_struct
{
    static int read( int, void*, size_t n){return 0;}
};

class Serial
{
    public:
        int read( int, void*, size_t n ) { return 0; }
};

int main()
{
    char buf[5];
    read( 0, buf, 5); // call to c-library
    serial_ns::read( 0,buf,5);
    serial_struct::read( 0,buf,5);

    // with an object:
    Serial ser;
    ser.read( 0,buf,5);
}

【讨论】:

    猜你喜欢
    • 2016-03-27
    • 1970-01-01
    • 2011-07-02
    • 1970-01-01
    • 2014-03-12
    • 2015-03-21
    • 1970-01-01
    • 2013-11-13
    • 2017-10-08
    相关资源
    最近更新 更多