我有一个编程项目,需要访问一些较低级别的Windows API(特别是WASAPI)。我对C#,Java和PHP等高级编程语言很有经验,而且我对C / C ++只有一点了解。
我想在这个项目中使用C(而不是C ++),C++ is kind of scary。在Visual Studio中更改我的项目的C / C ++设置以编译为C代码后,我注意到对__uuidof
的任何调用都不起作用,因为它们是C ++特定的。
我的问题有两个:
答案 0 :(得分:4)
是的,可以使用使用COM的写纯C程序,事实上这是10 - 15年前的常见做法。
使用C(你已经注意到了),你并没有帮自己一个忙。例如。在您做COM时,ATL提供了很多帮助,可以帮助您避免常见错误。
如果我是你,即使最初的阈值可能稍微高一点,我也会使用C ++。如果您没有该书,也可以获得该主题的书籍。网上有很多例子,但是有一些东西可以引导你,因为COM编程不适合胆小者,无论你使用的是C还是C ++。
答案 1 :(得分:4)
COM在C部分之外使用了相当小的C ++子集,并且不需要使用许多“可怕”的项目,例如:
例外 - 如果你没有把它们弄好,你可能真的会用C ++来咬你(你需要真正购买RAII成语,如果你已经习惯了,这可能会习惯更传统的C / Win32编码);但异常根本不是COM的一部分:COM使用返回代码进行所有错误处理。如果你愿意,有一些包装器和编译器扩展可以将COM的返回代码转换为C ++异常,但它是选择加入的。
类层次结构和继承 - 继承也不是COM本身的一部分,除了所有COM接口派生自(或从IKnknown方法开始)的事实。但是,您无需了解有关使用 COM的多个虚拟继承的任何信息。其中一些非常有用,可以了解您是自己实现 COM对象,而不仅仅是使用它。 (例如,使用C ++多重继承是实现暴露多个接口的COM对象的一种非常常见的方式;但这不是唯一的方法。)
模板 - 再次,不是COM的一部分,但有几个库 - 例如。 MFC和ATL - 使用模板使COM更易于使用。对于像CComPtr这样的智能指针类来说尤其如此,它会为你处理一些引用计数,让你的代码专注于做真正有趣的事情,而不是让它包含管家的东西。
COM和C ++之间的主要联系是Windows上的所有C ++编译器都会以与COM所需内容完全匹配的方式在内存中布局C ++对象。这允许您使用COM对象,就像它是一个C ++对象一样,这使得代码相当简洁,因为语言/编译器会为您处理一些非常简单但冗长的内容。
所以不要在C中执行以下操作(逐步执行vtable并明确传递此参数):
pUnk->lpVtbl->SomeMethod(pUnk, 42);
您可以在C ++中执行以下操作:
pUnk->SomeMethod(42);
你真的不想输入 - > lpVtbl并确保你传递正确的'this'参数(切割和粘贴时要小心!),你做的每一个COM调用,对吗?
我的建议是找到一本好的COM书 - 内部COM是一个很好的 - 并且开始使用你熟悉的C ++子集。一旦你知道如何使用COM指针“raw”,并自己使用QI,AddRef等,那么也许你可以使用帮助库来使用模板为你做一些簿记。决定使用将COM错误映射到C ++异常的包装器是一个更大的跳跃,因为您需要首先编写异常安全的C ++代码,因此需要首先了解这些问题。但我想不出任何好的理由 - 除了纯粹的好奇心 - 回归并使用普通的C语言。