所以我想将我的应用程序构建为独立于平台,以便它可以在Windows,OSX,Linux等上运行。
例如,平台上不同的主要“部分”之一是Window。在Windows上,它将使用Win32 API,在OSX,Linux上,我想它会使用其他东西。
我有一个IWindow.h类,它是一个与Window和MSWindow类交互的接口,它封装了所有Win32函数并扩展了IWindow接口。
将来我会创建一个OSXWindow类等等
所以我的两个问题点是:
#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
显然RUNNING_WINDOWS和RUNNING_OSX组成了,如果有人知道我可以查找的实际标记,那将是值得赞赏的。
//Main Entry point to windows application int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
并且必须将hInstance传递给MSWindow类。这提出了一个问题,因为我的IWindow接口无法接受HINSTANCE,因为HINSTANCE是Windows的一部分,在OSX或Linux上不存在。我的main.cpp中是否有单独的入口点函数被ifdefs阻塞?
IWindow会有一个Init函数,它也会根据ifdef接受不同的参数吗?
#ifdef RUNNING_WINDOWS
bool Init(HINSTANCE* hInstance);
#elif RUNNING_OSX
bool Init(Whatever OSX needs);
#endif
我可能会认为这一切都是错的,所以希望你可以进来让我走上正确的道路。
谢谢!
编辑:
根据以下评论,我将添加更多有关我的目标的信息。
基本上我有一个核心类是我的应用程序。我的main.cpp实例化了这个Core类的一个实例,而且几乎就是它。
Core类将具有Window类的实例。核心不应该关心它是什么类型的窗口,它只需要与它进行交互。
然后,我收集的Window本身(从下面的评论中)将内部处理平台独立性方面。因此,由于#ifdef块,Window可能会变得混乱,但应用程序的其余部分以及与Window交互的任何内容都不会关心。我采用的另一个选项和第一个方向是,每个“Type”的Window实现都有一个单独的类,它们来自一个常见的IWindow接口。然后#ifdefs将在Core中发生,以实例化和包含哪种类型。虽然这将OS的实现分开,但我同意它会使Core混乱,如果Application的任何其他未来部分需要引用Window,那么它还需要#ifdef块,这只会导致整个代码更加混乱。
答案 0 :(得分:2)
实际上,最好的方法是通过创建一个包装Window的类来封装Window的整个概念。然后,这个类可以通过非API特定的函数提供所需的接口,因此使用它的东西甚至不需要知道你将要使用的Win32 API,GTK或其他任何窗口系统如何工作。简而言之,您不希望每次需要启动窗口时都使用#ifdef
,但希望将它们隐藏在其他类中。我已经使用Qt Framework作为一个非常强大的跨平台框架来实现这一点,并允许在Windows,Mac,Linux和其他平台上编译相同的C ++。它提供对Windowing系统的跨平台标准化访问,网络连接,线程,媒体播放,文件系统访问等等。
如果你真的想重新发明轮子并编写自己的包装类,你应该查看定义的编译器特定宏,以确保你想要支持的平台到位。这是一个寻找macros are defined on what platforms by what compilers的好地方。一些常见的宏是_WIN32用于Visual Studio编译,而__unix__用于基于Unix的平台。
答案 1 :(得分:2)
我做过类似的事情,所以我可以提供一些建议。
虽然可以调用你的Window类MSWindow,OSXWindow等,但这真的不方便,因为需要与Window交互的代码的每个部分都需要知道哪一个使用。你应该只调用这些类Window。由于您只会在给定平台中编译其中一个,因此不会发生冲突。
检查给定操作系统的宏:
_WIN32
for Windows __APPLE__
用于OSX和iOS(我在pch文件中设置了自己的常量来区分这两个)__linux__
for Linux 我建议您不要在上面添加#define
。如果您将跨平台特定代码放在尽可能少的位置,您将拥有更多可移植代码。
您将在每个平台上拥有不同的主要功能。 Windows上为WinMain()
,其他人为main()
。我建议您将它们放在不同的文件中,并且只引用与makefile或项目文件中的正确平台对应的文件。
您提出的HINSTANCE问题很容易解决。在WinMain()函数中,您将HINSTACE赋予Window类。 Windows上的Window类将有一个静态方法,比方说setHinstance()
,它将HINSTACE存储在类变量中。然后,当创建一个Window实例时,HINSTACE将可用而无需更改此类的常用方法。
作为最后的评论,您应该记住,有几个跨平台的GUI框架可能对您有用。如果你想要一个功能齐全的,请看Qt。如果你想要一个非常简单的(有一些不错的功能,但没有Qt那么多),那么看看FLTK。 Qt和FLTK都是开源的。