COM C#,如何使用C ++调用COM

时间:2013-05-05 01:31:39

标签: c# c++ com

我使用了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;

3 个答案:

答案 0 :(得分:2)

如果您的代码有效,那么因为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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

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

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

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

现在,selbie是正确的,您的界面名称末尾的PTR是您的界面的智能指针。为了您的目的,它基本上是透明的,可以被视为只是和ICalc对象。但是它会自动为您清理。 ICalcPtr是在幕后为您生成的。