【问题标题】:COM C#, How to use C++ to call COMCOM C#, 如何使用 C++ 调用 COM
【发布时间】:2013-04-29 03:16:06
【问题描述】:

我使用了一个 C# COM 的在线示例,并通过 C++ 调用它。下面是C#的COM代码,只有一个接口“ICalc”和一个类“Calc”。

namespace COMLib
{
[Guid("F40D7BC9-CF53-4613-AA5E-F269AD73808F")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ICalc
{
    [DispId(1)]
    long Factorial(int n);
}

[Guid("8EE38F2E-75BE-4B45-87B6-3F6D15FDBBC5")]
[ClassInterface(ClassInterfaceType.None)]
[ComSourceInterfaces(typeof(ICalc))]
[ProgId("MyCalc")]
public class Calc : ICalc
{
    long ICalc.Factorial(int n)
    {
        long fact = 1;
        for (int i = 1; i <= n; i++)
            fact *= i;
        return fact;
    }
}
}

以下代码在 C++ 中调用此函数。它是有效的。但是,我对第二行中的代码感到困惑。 “ICalcPtr”从何而来?还是这是某种机制?

CoInitialize(NULL);
    COMLib::ICalcPtr pCalc;
    HRESULT hRes = pCalc.CreateInstance(__uuidof(COMLib::Calc));
    if(FAILED(hRes))
        printf("ICalcPtr::CreateInstance failed w/err 0x%08lx\n", hRes);
    else
    {
        printf("%d\n", pCalc->Factorial(3));
    }
    system("pause");
    CoUninitialize();
    return 0;

【问题讨论】:

标签: c# c++ com


【解决方案1】:

如果你的代码有效,那是因为在 C++ 项目的某个地方,定义了以下语句(例如,如果你使用 #import directive,它是自动的):

_COM_SMARTPTR_TYPEDEF(ICalc, __uuidof(ICalc));

_COM_SMARTPTR_TYPEDEF 是一个在ICalc 上定义“智能指针”的宏。这是一个 Microsoft Visual C++ 神奇的扩展,用于更轻松的 COM 支持。官方文档在这里:_com_ptr_t Class

智能指针通常由 typedef 定义引用 _COM_SMARTPTR_TYPEDEF 宏提供。这个宏需要一个 接口名称和 IID 并声明 _com_ptr_t 的特化 接口名称加上后缀Ptr

【讨论】:

  • 谢谢,这正是我需要的。顺便说一句,我是 COM 和智能指针的更新者。你建议我需要学习什么,因为我面临一个需要使用基于 COM 的 API 的项目。我手头有>。
  • 哇,这在我的脑海里已经过时了 :-) 我有 Essential COM 是的,还有 Wrox 的“专业 DCOM 编程”、“专业 ATL COM 编程”以及“ATL 内部:”。请注意,如果您了解 ATL,您将了解 COM 的真正工作原理。 ATL 不是必需的,但它是学习 COM 的一种方式。
  • 至少阅读“基本 COM”的前 4 章 - 它涵盖了编写 COM 客户端所需了解的 >90%。不过,.NET 和 C++ 之间的 COM 互操作部分可能很复杂。
  • 谢谢你们。你很有帮助
【解决方案2】:

我不确定您使用什么工具将 .NET 类导出到 C++,但我怀疑 COMLib::ICalPtr 只是智能指针类的 typedef,它管理其中的底层原始指针。

您是否尝试过在调试器中单步执行以查看 CreateInstance 的实现是做什么的?我怀疑您会看到最终调用 CoCreateInstance 和可能 QueryInterface 的自动生成的代码。也许一些代码可以将 Factorial 等方法转换为 IDispatch::Invoke() 调用。

【讨论】:

    【解决方案3】:

    ICalcPtr 保存由 COM 创建的类的实例。

    出于同样的原因,我们不能从 c++ dll 导出类,COM 对象必须返回到接口。

    http://www.codeproject.com/Articles/28969/HowTo-Export-C-classes-from-a-DLL

    这篇文章帮助我理解了这个概念。

    现在,selbie 是正确的,接口名称末尾的 PTR 是指向接口的智能指针。出于您的目的,它本质上是透明的,可以将其视为只是 ICalc 对象。但是,它会自动为您进行清理。 ICalcPtr 在幕后为您生成。

    【讨论】:

      猜你喜欢
      • 2015-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-26
      • 2021-02-16
      • 1970-01-01
      • 2010-10-06
      • 1970-01-01
      相关资源
      最近更新 更多