【问题标题】:How do you declare an extern global in a namespace and then define it?如何在命名空间中声明 extern 全局然后定义它?
【发布时间】:2017-07-15 05:18:20
【问题描述】:

似乎每个 Arduino 库都使用 Arduino 串行库来打印调试消息。我目前正在尝试将此库集成到我的项目https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/I2Cdev 中。我正在使用我自己的 python 程序从我的 atmega 2560 接收消息。我想在不更改其源代码的情况下尝试一些库,但由于 Serial 库,我必须将它们的 Serial.print() 调用转换为我自己的 API 调用.因为我必须为我遇到的每个库都这样做,所以我决定为 Serial 库创建一个包装器,其中我有一个名为 Serial 的全局变量。然后,那个 Serial 变量将是我定义为外部的 Serial 包装器。

我在serial 命名空间中有SerialWrapper。我希望将全局变量 Serial 定义为 extern,也在 serial 命名空间中。

// SerialWrapper.h
namespace serial {

    enum SerialType {
        HEX,
        DEC
    };

    class SerialWrapper {
    public:
        SerialWrapper(ground::Ground& ground);
        void print(const char *string);
        void print(uint8_t data, SerialType type);
    private:
        ground::Ground& ground_;
    };

    extern SerialWrapper Serial;
}

然后在源文件中定义方法和全局变量,像这样

// SerialWrapper.cpp
#include "SerialWrapper.h"

serial::SerialWrapper Serial = serial::SerialWrapper(ground::Ground::reference());

serial::SerialWrapper::SerialWrapper(ground::Ground& ground) : ground_( ground )
{

}

void serial::SerialWrapper::print(const char *string)
{
    ground_.sendString(string);
}

void serial::SerialWrapper::print(uint8_t data, serial::SerialType type)
{

}

试图测试这个库,我在我的 main 方法中调用它

// main.cpp
using namespace serial;

int main( void )
{
    Serial.print("Hello World!");
}

为了使库与我的SerialWrapper 兼容,我需要它以这种方式工作。但是,当我编译时,我从 main.cpp 收到错误消息,即存在 undefined reference to 'serial::Serial'

你可以在这里https://github.com/jkleve/quaddronehttps://github.com/jkleve/quaddrone看到我所有的mpu分支下的源代码(即将合并到master)

【问题讨论】:

标签: c++ namespaces extern


【解决方案1】:

为了让未定义的引用消失,我不得不像这样将声明移到命名空间之外

// SerialWrapper.h
namespace serial {

    enum SerialType {
        HEX,
        DEC
    };

    class SerialWrapper {
    public:
        SerialWrapper(ground::Ground& ground);
        void print(const char *string);
        void print(uint8_t data, SerialType type);
    private:
        ground::Ground& ground_;
    };
}

extern serial::SerialWrapper Serial;

我不知道为什么必须这样做。也许其他人可以评论在命名空间中声明 extern 的问题。

我还找到了这个参考https://www.ics.com/designpatterns/book/namespace-example.html

按照参考资料中的方法,您还可以按如下方式设置声明和定义

// SerialWrapper.h
namespace serial {

    enum SerialType {
        HEX,
        DEC
    };

    class SerialWrapper {
    public:
        SerialWrapper(ground::Ground& ground);
        void print(const char *string);
        void print(uint8_t data, SerialType type);
    private:
        ground::Ground& ground_;
    };
    extern SerialWrapper Serial;
}

定义必须改成这个。

// SerialWrapper.cpp
#include "SerialWrapper.h"

serial::SerialWrapper serial::Serial = serial::SerialWrapper(ground::Ground::reference());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-22
    • 1970-01-01
    • 2019-09-21
    • 2019-10-29
    • 2018-07-24
    • 2013-08-16
    • 1970-01-01
    • 2013-08-11
    相关资源
    最近更新 更多