【问题标题】:Static constructors in C++ on my own OS kernel我自己的操作系统内核上的 C++ 中的静态构造函数
【发布时间】:2023-03-08 00:19:01
【问题描述】:

我正在尝试用 c++ 编写内核,并且我是操作系统开发的初学者。现在我正在实现cout 在显示器上显示,但我遇到了一些问题。我知道我问的问题很愚蠢,但我也是 C++ 的新手。

我写了一个 OStream 类,它调用系统函数write 在屏幕上显示。它的基类是我的 Video 类。此类包含在命名空间 std 中。所以主要的问题是,当我创建一个 OStream 对象时,它没有调用它的构造函数,因此没有调用其基类的构造函数,因此视频内存没有初始化,因此屏幕上不会显示任何内容。

这是我的代码:

/*OStream.h*/
namespace std{
class OStream:public Video{
    public:
    OStream();
    OStream& operator<<(int);
    OStream& operator<<(String);
    OStream& operator<<(char *cp);
    OStream& operator<<(char c);
    OStream& operator<<(unsigned char *cq);
    OStream& operator<<(unsigned char c1);
};
extern OStream cout;
}

/*OStream.cpp*/
namespace std{
    OStream cout;
    OStream::OStream(){}
    OStream& OStream::operator<<(char *cp){
        write(cp);
    }
    .
    . 
    .
    .
}

在上面的代码中,我在 OStream.cpp 文件本身中创建了一个 OStream 类的对象。 但是如果我在我的主模块中创建一个对象,那么它会成功调用它的构造函数,但是cout 不起作用。

这意味着如果我显式创建一个对象,它可以完美运行,但我如何才能隐式创建一个对象。

我的 Interrupt.cpp 模块也在发生同样的事情。

所以请帮我解决这类问题。 请帮我。 任何帮助将不胜感激。 谢谢。

【问题讨论】:

  • 你说你是内核开发和C++的新手。两者都非常复杂。我建议您一次只专注于一个。先学C++,再搞内核。
  • 在编写自己的内核时,我也考虑过使用 C++,但这真的不值得额外的麻烦。无论如何,在中断工作、分页支持、内核堆等之前,你不能在开始时使用任何标准库(C 或 C++)。所以这必须与语言的基本功能一起工作(这对于 c 和 c++ 基本相同)。稍后您可以轻松地将这两个库移植到您的内核中,但这确实不是您现在应该担心的事情。

标签: c++ operating-system kernel osdev


【解决方案1】:

首先,您对cout 的实现不符合要求。如果您要编写 C++ 标准库,则必须编写它以符合上述标准(而不是您认为的标准)。

其次,您需要实现静态构造函数支持。你还没有指定你的编译器,所以我只能说弄清楚你的编译器把它的静态构造函数初始化代码放在哪里,并确保在程序启动时调用它。

与从头开始编写一个库相比,将现有的 C++ 库(GCC 的 libstdc++ 或 clang 的 libc++)适应新操作系统可能会更幸运。编写 C++ 标准库不是初学者的事。您很快就会精通模板元编程。

【讨论】:

  • 感谢您的回复。对不起,我忘了说我正在使用的编译器。我正在使用GCC编译器构建内核。
  • 如何使用 GCC 的标准库。在运行 OS 时,没有任何 OS 运行时环境。所以我是否应该实现它?
  • @Dnyanesh,好的,现在去看看 GCC 用静态构造函数编译文件时的程序集输出。你需要弄清楚如何调用它发出的静态构造代码(也看看 glibc,实际调用发生在 Linux 上)
  • 如果你正在编写你的操作系统,你可以创建任何你想要的运行时环境。您没有指定这是针对您的操作系统的用户空间还是内核空间;如果这是针对内核的,我建议您只使用 C,或者使用非常有限的 C++ 子集(无静态构造函数、无异常、有限分配等)
【解决方案2】:

如果不调用它的构造函数,就不可能创建一个对象。但是对于像cout 这样的全局变量,有时调用构造函数的时间是个问题。如果您在不同的 .cpp 文件中有两个全局变量,那么您无法预测首先构造哪个全局变量。也许这就是你看到的问题?如果是这样,那么简单的答案是将所有全局变量放入一个 .cpp 文件中(如果您愿意,可以将其称为 globals.cpp)。然后全局变量将按照您在该 .cpp 文件中声明它们的顺序构造(并以相反的顺序销毁)。

【讨论】:

  • 如果您正在编写自己的操作系统,那么一切皆有可能,包括全局对象,而无需调用其构造函数。这是一个关于实现 C++ 本身,而不是使用它的问题。
  • 是的,只有当我在 OStream.cpp 文件本身中创建一个对象并且我在 OStream.h 中将其声明为 extern 以使用另一个模块时才会发生这种情况。我只创建一个该类的对象。
猜你喜欢
  • 2011-11-05
  • 2010-10-09
  • 1970-01-01
  • 2011-05-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
  • 2019-06-02
相关资源
最近更新 更多