【问题标题】:Is there a way to contain WinAPI in something for safety and to prevent naming conflicts?有没有办法在某些东西中包含 WinAPI 以确保安全并防止命名冲突?
【发布时间】:2020-03-11 00:57:35
【问题描述】:

我想在命名空间或其他东西中包含 WinAPI。在没有链接问题的情况下这可能吗?如果无法使用命名空间,是否有一些替代的首选方法?

【问题讨论】:

  • WinAPI 有什么问题?链接时名称冲突?还是丑陋的宏妨碍了?
  • 您可以使用您选择的名称声明 Windows API 函数(例如,通过使用前缀将它们移动到命名空间),并使用 #pragma comment(linker, "/alternatename:MySymbol=RealSymbol") 指令,以允许链接器匹配您的符号与出口。
  • @hol:问题可能不是 Windows API,而是#include <Windows.h> 指令,它引入了大量的预处理器宏。如果您的库包含一个名为 CreateWindow 的符号,那么如果您包含 Windows.h 标头,您将不可避免地遇到问题。
  • @rem:我过去尝试过,发现它只解决了一半的问题。它允许库的实现者引入一个符号,否则该符号会与 Windows SDK 标头中定义的预处理器宏发生冲突。但是,如果该库的客户端也包含 Windows SDK 标头,则它对它们没有帮助。对于库的实现者和客户,我上面说明的方案更易于维护。对于实际用例,您可以查看从版本 17134 开始随 Windows SDK 一起提供的 C++/WinRT 标头 (base.h)。
  • 至于原来的问题,能否请您强调一下您要解决的具体问题?

标签: c++ winapi c++17


【解决方案1】:

在 C++ 中?并不真地。 Windows API 是一个 C api,因此您不能将它存储在命名空间中。它还使用了很多宏,因此以通用方式安全处理它的唯一方法就是隔离它。

因此,您必须首先为您想要使用的所有 winapi 位声明一组抽象基类。他们会公开静态工厂函数或其他“聪明”的方法来获得它们的功能:作为实际执行 #include 作为其最终 #include 语句的实现类然后将根据 winapi 调用实际实现它们的功能。

// shared / clean framework classes
#pragma once
namespace win32 {
  class file {
    public:
      static file* create(string filename);
      virtual void read();
      virtual void close();
  };
} 

一些肮脏的实现hpp文件

#include "win32/file.h"
// this always comes last.
#include <windows.h>

namespace win32 {

  class Win32FileImpl : public Win32File
  {
    HANDLE hf;
  public: 
    static Win32File* create(string filename)
    {
       auto file = new Win32File();
       file->open(filename);
       return file;
  }
  // etc...
}

这将花费很长时间,而且我认为这不值得花费时间和精力,尤其是因为最终的框架在如何分配、复制和释放类方面会非常固执己见。

【讨论】:

  • 是的,我不知道我要去哪里。
  • 虽然这仅用于说明机制,但实现仍有很多不足之处。使用 C++11 的移动语义,几乎没有理由使用原始指针。只需构造一个具有自动存储持续时间的Win32File 对象并将std::move 发送给调用者即可。看看 WIL 的 RAII resource wrappers 看看,从 C++11 开始应该如何进行资源管理。
  • 天哪,是的。有很多东西要实施。这确实是这种方法失败的地方。正如我所说 - 它变得非常固执:当实现 RAII 或其他一些模式时,你严格限制消费者在你的框架中调用类的方式:他们可以简单地使用“new Something”还是他们使用工厂方法(something::createSomething),还是他们总是声明SomethingWrapper something();,或者是所有东西都包裹在std::shared_ptr或类似的句法噪音中。
猜你喜欢
  • 2014-04-01
  • 2019-08-12
  • 1970-01-01
  • 2014-11-22
  • 1970-01-01
  • 1970-01-01
  • 2017-04-02
  • 2014-03-03
  • 2013-11-25
相关资源
最近更新 更多