5

我有一个编程项目,它需要访问一些较低级别的 Windows API(特别是 WASAPI)。我对 C#、Java 和 PHP 等高级编程语言相当有经验,而且我对 C/C++ 知之甚少。

我想在这个项目中使用 C(不是 C++),因为C++ 有点吓人。在 Visual Studio 中更改我的项目的 C/C++ 设置以编译为 C 代码后,我注意到任何调用__uuidof都不起作用,因为它们是 C++ 特定的。

我的问题是双重的:

  1. 是否可以在纯 C 中编写使用 COM 的 Win32 程序,以及
  2. 如果是这样,是否应该避免使用纯 C?
4

2 回答 2

4
  1. 是的,可以使用编写使用 COM 的纯 C 程序,实际上这是 10-15 年前的常见做法。

  2. 使用 C 并没有帮自己一个忙(正如您已经注意到的那样)。例如,ATL 在你做 COM 时提供了很多帮助,可以帮助你避免常见的错误。

如果我是你,我会选择 C++,即使一开始的门槛可能会更高一些。如果你没有这方面的书,也可以买一本。在网上可以找到很多示例,但最好有一些手把手指导你的东西,因为无论你使用 C 还是 C++,COM 编程都不适合胆小的人。

于 2013-02-07T07:14:52.633 回答
4

COM 在 C 部分之外使用了相当小的 C++ 子集,并且不需要使用许多“可怕”的项目,例如:

  • 例外——如果你没有把它们弄对,这些真的会在 C++ 中咬你(你需要真正购买RAII习语,如果你习惯于更传统的 C/Win32 编码,这可能需要习惯);但异常根本不是 COM 的一部分:COM 对所有错误处理都使用返回码。如果需要,有一些包装器和编译器扩展可以将 COM 的返回代码转换为 C++ 异常,但它是可选的。

  • 类层次结构和继承——继承也不是 COM 本身的真正组成部分,除了所有 COM 接口都派生自(或从方法开始)IUnknown 的事实。但是您不需要了解有关多重虚拟继承的任何知识即可使用COM。其中一些对于了解您是否自己实现COM 对象非常有用,但不仅仅是使用它。(例如,使用 C++ 多重继承是实现公开多个接口的 COM 对象的一种非常常见的方法;但这不是唯一的方法。)

  • 模板 - 同样,不是 COM 的一部分,但有几个库 - 例如。MFC 和 ATL - 使用模板使 COM 更易于使用。对于像 CComPtr 这样的智能指针类来说尤其如此,它会为你处理一些引用计数,让你的代码专注于做真正有趣的事情,而不是把它打包成家务。

COM 和 C++ 之间的主要联系是 Windows 上的所有 C++ 编译器将以完全符合 COM 要求的方式在内存中布置 C++ 对象。这使您可以像使用 C++ 对象一样使用 COM 对象,这使得代码的冗长程度大大降低,因为语言/编译器正在为您处理一些非常简单但冗长的东西。

因此,不要在 C 中执行以下操作(逐步通过 vtable 并显式传递此参数):

pUnk->lpVtbl->SomeMethod(pUnk, 42);

您可以在 C++ 中执行以下操作:

pUnk->SomeMethod(42);

您真的不想在每次调用 COM 时都键入 ->lpVtbl 并确保传递正确的“this”参数(剪切和粘贴时要小心!),对吗?

我的建议是找一本好的 COM 书——《Inside COM》是一本好书——然后开始使用你熟悉的 C++ 子集。一旦您知道如何使用“原始”COM 指针,并自己使用 QI、AddRef 等,那么也许您可以使用使用模板为您做一些簿记的帮助程序库。决定使用将 COM 错误映射到 C++ 异常的包装器是一个更大的跳跃,因为您需要首先编写异常安全的 C++ 代码,因此需要首先了解这些问题的各种问题。但是我想不出任何好的理由——除了纯粹的好奇心——回去使用纯 C 中的 COM。

于 2013-02-07T09:05:35.923 回答