简体   繁体   English

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

[英]COM C#, How to use C++ to call COM

I used a online example of C# COM and call it through C++. 我使用了C#COM的在线示例,并通过C ++调用它。 The following is the C# COM code, only one interface "ICalc" and one class "Calc". 以下是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;
    }
}
}

The following code is in C++ to call this this function. 下面的代码在C ++中用来调用这个函数。 It is worked. 这是有效的。 However, I am confused with the code in second line. 但是,我对第二行的代码感到困惑。 where is the "ICalcPtr" come from? “ICalcPtr”来自哪里? Or is this some mechanism? 或者这是一些机制?

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;

If you code works, its because somewhere in the C++ project, there is the following statement defined (it's automatic if you used a #import directive for example): 如果您编写代码,那么因为C ++项目中的某个地方,定义了以下语句(例如,如果您使用了#import指令 ,它是自动的):

_COM_SMARTPTR_TYPEDEF(ICalc, __uuidof(ICalc));

_COM_SMARTPTR_TYPEDEF is a macro that defines a "smart pointer" on ICalc . _COM_SMARTPTR_TYPEDEF是一个在ICalc上定义“智能指针”的ICalc It's a Microsoft Visual C++ magical extension for easier COM support. 它是一个Microsoft Visual C ++神奇扩展,可以更轻松地支持COM。 The official documentation is here: _com_ptr_t Class 官方文档在这里: _com_ptr_t类

A smart pointer is usually referenced by the typedef definition provided by the _COM_SMARTPTR_TYPEDEF macro. 智能指针通常由_COM_SMARTPTR_TYPEDEF宏提供的typedef定义引用。 This macro takes an interface name and the IID and declares a specialization of _com_ptr_t with the name of the interface plus a suffix of Ptr . 此宏采用接口名称和IID,并使用接口名称加上后缀Ptr声明_com_ptr_t的特化。

I'm not sure what tools you used to export the .NET class to C++, but I suspect COMLib::ICalPtr is simply a typedef to a smart pointer class that manages an underlying raw pointer inside it. 我不确定你用什么工具将.NET类导出到C ++,但我怀疑COMLib :: ICalPtr只是一个智能指针类的typedef,它管理它内部的底层原始指针。

Have you tried stepping through in the debugger to see what the implementation of CreateInstance does? 您是否尝试在调试器中单步执行以查看CreateInstance的实现是什么? I suspect you see auto-generated code that eventually calls CoCreateInstance and possibly QueryInterface. 我怀疑你看到自动生成的代码最终调用CoCreateInstance和可能的QueryInterface。 Maybe some code to translate methods like Factorial into IDispatch::Invoke() calls. 也许有些代码将Factorial等方法转换为IDispatch :: Invoke()调用。

ICalcPtr holds the instance of your class that is created by COM. ICalcPtr保存由COM创建的类的实例。

For the same reason we cannot export classes from a c++ dll, COM objects must be returned to an interface. 出于同样的原因,我们无法从c ++ dll导出类,必须将COM对象返回到接口。

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

This article helped me understand the concept. 这篇文章帮助我理解了这个概念。

Now, selbie is correct, the PTR at the end of your interface name is a smartpointer to your interface. 现在,selbie是正确的,接口名称末尾的PTR是您的界面的智能指针。 For your purposes it's is essentially transparent and can be treated as if it was just and ICalc object. 为了您的目的,它基本上是透明的,可以被视为只是和ICalc对象。 It will however take care of cleanup for you automatically. 但是它会自动为您清理。 ICalcPtr is generated for you behind the scenes. ICalcPtr是在幕后为您生成的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM