C++ 具有C+的平台独立性+;。检测与编译

C++ 具有C+的平台独立性+;。检测与编译,c++,cross-platform,C++,Cross Platform,因此,我希望将我的应用程序构建成独立于平台的,这样它就可以在Windows、OSX、Linux等平台上运行 例如,不同平台的一个主要“部分”是一个窗口。在Windows上,它将使用Win32 API,在OSX、Linux上,我想它将使用其他东西 我有一个IWindow.h类,它是一个与窗口交互的接口,还有一个MSWindow类,它封装了所有Win32函数并扩展了IWindow接口 将来我会创建一个OSXWindow类等 所以我的两个问题是: 在某个时刻,我需要检测我在哪个平台上运行,并实例化正确

因此,我希望将我的应用程序构建成独立于平台的,这样它就可以在Windows、OSX、Linux等平台上运行

例如,不同平台的一个主要“部分”是一个窗口。在Windows上,它将使用Win32 API,在OSX、Linux上,我想它将使用其他东西

我有一个IWindow.h类,它是一个与窗口交互的接口,还有一个MSWindow类,它封装了所有Win32函数并扩展了IWindow接口

将来我会创建一个OSXWindow类等

所以我的两个问题是:

  • 在某个时刻,我需要检测我在哪个平台上运行,并实例化正确的类。我想我必须为include做一些ifdef块,然后还要实例化本身
  • 我可能会把这一切都搞错,所以希望这就是你能进来的地方,让我走上正确的道路

    谢谢

    编辑:

    根据下面的评论,我将补充一些关于我的目标的更多信息

    本质上,我有一个核心类,它是我的应用程序。我的main.cpp实例化了这个核心类的一个实例,基本上就是这样

    核心类将有一个窗口类的实例。核心不应该关心它是什么样的窗口,它只需要与它交互

    然后(从下面的评论中)窗口本身将在内部处理平台独立性方面。因此,由于#ifdef阻塞,窗口可能会很混乱,但应用程序的其余部分以及与窗口交互的任何内容都不会在意


    我采取的另一个选择和第一个方向是,对于从通用iWindows接口派生的每个“类型”的窗口实现,都有单独的类。然后#ifdef将发生在要实例化和包含的类型的核心中。虽然这将整个操作系统的实现分开,但我同意它确实会使核心变得混乱,如果应用程序的任何其他部分需要引用窗口,它还需要有#ifdef块,这只会导致整个代码更加混乱。

    真的,最好的方法是通过创建一些封装窗口的类来封装窗口的整个概念。然后,这个类可以通过非特定于API的函数提供所需的接口,这样使用它的东西甚至不需要知道Win32 API、GTK或任何您将要使用的其他窗口系统是如何工作的。简而言之,您不希望每次需要启动窗口时都必须使用
    #ifdef
    ,而是希望将它们隐藏在其他类中。我使用了一个非常强大的跨平台框架,它可以做到这一点,并允许在Windows、Mac、Linux和其他平台上编译相同的C++。它提供了对窗口系统、网络连接、线程、媒体播放、文件系统访问等的跨平台标准化访问


    如果您真的想重新发明轮子并编写自己的包装器类,那么您应该查看特定于编译器的宏,这些宏是为确保您想要支持的平台就位而定义的。这里有一个好地方可以找什么。一些常见的宏是用于Visual Studio编译的WIN32和用于基于unix平台的unix。实际上,最好的方法是通过创建一些封装窗口的类来封装窗口的整个概念。然后,这个类可以通过非特定于API的函数提供所需的接口,这样使用它的东西甚至不需要知道Win32 API、GTK或任何您将要使用的其他窗口系统是如何工作的。简而言之,您不希望每次需要启动窗口时都必须使用
    #ifdef
    ,而是希望将它们隐藏在其他类中。我使用了一个非常强大的跨平台框架,它可以做到这一点,并允许在Windows、Mac、Linux和其他平台上编译相同的C++。它提供了对窗口系统、网络连接、线程、媒体播放、文件系统访问等的跨平台标准化访问


    如果您真的想重新发明轮子并编写自己的包装器类,那么您应该查看特定于编译器的宏,这些宏是为确保您想要支持的平台就位而定义的。这里有一个好地方可以找什么。一些常见的宏是用于Visual Studio编译的WIN32宏和用于基于unix平台的unix宏。

    我做过类似的工作,因此我可以提供一些建议

    • 虽然可以调用窗口类MSWindow、OSXWindow等,但这并不方便,因为需要与窗口交互的代码的每一部分都需要知道使用哪一个。您应该将这些类称为Windows。由于您将只在给定平台中编译其中一个,因此不会发生冲突

    • 要检查给定操作系统的宏:

      • \u WIN32
        适用于Windows
      • \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
      • 适用于linux的linux
    • 我建议您不要添加
      #define
      ,上面的内容到处都是。如果您将跨平台的特定代码放在尽可能少的地方,您将拥有更多的可移植代码

    • 您将在每个平台上拥有不同的主要功能WinMain(),其他系统上的代码>main()。我建议您将这些文件放在不同的文件中,并且只引用makefile或项目文件中与正确平台对应的文件

    • 你问的问题很容易解决。在WinMain()函数中,您将为窗口类提供HINSTACE。Windows上的Window类将有一个静态方法,比如说
      setHinstance()
      ,即 #ifdef RUNNING_WINDOWS #include #elif RUNNING_OSX #include #endif //m_window is declared as IWindow* m_window; #ifdef RUNNING_WINDOWS m_window = new MSWindow(); #elif RUNNING_OSX m_window = new OSXWindow(); #endif //Main Entry point to windows application int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
      #ifdef RUNNING_WINDOWS
      bool Init(HINSTANCE* hInstance);
      #elif RUNNING_OSX
      bool Init(Whatever OSX needs);
      #endif