您好我正在尝试找到一种方法来阻止包含特定于平台的头文件,例如windows.h。 奇怪的是,我发现的解决方案都不令我满意。也许它无法实现。
我认为要实现这一目标需要使用几种技术。互联网上有很多例子,但我找不到任何关于一个方面的例子。有些东西必须与你的抽象交谈/创造。这是一个例子:
这是渲染窗口渲染目标的真正简化版本。
//D3D11RenderWindow.h
#include <d3d11.h>
class D3D11RenderWindow: public GfxRenderWindow
{
public:
bool initialize(HWND windowHandle);
private:
HWND windowHandle_; /// Win32 window handle
};
这不是问题所在,这是一个平台特定的代码,只能由特定于平台的代码包含在内。但我们需要真正实现此类型,因此“入口点”也需要了解特定于平台的代码。
例如工厂类:
//GfxRenderWindowFactory.h
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
class GfxRenderWindow;
class GfxRenderWindowFactory
{
public:
static std::unique_ptr<GfxRenderWindow> make(HWND windowHandle);
};
现在这个工厂类需要包含在库的“客户端”中(这里是渲染器)。我不喜欢的是#include“windows.h”,因为它太容易出错我,任何包含它的人,即使他们不需要它也会拥有所有的世界和窗口....预编译header不是解决方案,因为现在编译器强制所有cpp都包含它(它是加速编译时间的有用工具,但不是将平台特定代码与可移植代码分开的工具)
我认为将#include放在cpp之前,而不是在头文件中包含它,如下所示:
//GfxRenderWindowFactory.cpp
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h>
#include "GfxRenderWindowFactory.h"
/// Implementation of GfxRenderWindowFactory goed here ....
这种方式强制任何想要使用这个类的人都包含相关的平台特定标题,他们可以更好地判断他们是否将这个标题包含在一个糟糕的地方,就像在他们自己的一个头文件中一样。 / p>
你有什么解决方案? 你觉得我的解决方案怎么样?,疯了吗?
我想指出,对我而言,正确执行便携式代码是非常重要的!像只包括windows.h的答案,不要冒汗它不是一个有效的答案。对我来说这不是一个好的编码实践。
我希望我明白我的问题。如果不告诉我,我会澄清
非常感谢!
##编辑## 从与hmjd的小谈话中,我想在头文件中保留windows.h,因为我同意,这使得它更有用。因此,有一种方法可以防止包含在头文件中,这样就可以强制执行该文件只能包含在cpp中。这可能吗?
答案 0 :(得分:1)
使用预定义的宏(例如WIN32
)或构建系统定义的宏是不够的:
#ifdef WIN32
#include <windows.h>
#else
include other platform specific headers
#endif
这是一种常见的方法(FWIW是我用过的唯一方法)。
答案 1 :(得分:1)
由于基本问题是将HWND
传递给GfxRenderWindowFactory::make
,因此GfxRenderWindowFactory::make
没有HWND
。
答案 2 :(得分:0)
嘿,我参与了wxsmith跨平台GUI API。您需要做的第一件事是使用自己的句柄创建类。句柄是3件事之一:
使用如下函数:
#define create_handle(handle) struct __##handle{unsigned int unused;}; typedef __##handle *##handle;
然后调用此函数,它会创建一个struct和一个指向struct的指针。指针是句柄。然后施放到你想要的任何reinterpret_cast(你的手柄);然后你可以在你的目标文件或你的libs或dll中像这样投射。并为您的窗口句柄进行全局定义,研究其他操作系统如何做到这一点。