3

C# COM のオンライン例を使用し、C++ で呼び出しました。以下は C# COM コードで、1 つのインターフェイス "ICalc" と 1 つのクラス "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++ です。それは働いています。ただし、2行目のコードと混同しています。「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;
4

3 に答える 3

0

ICalcPtr は、COM によって作成されたクラスのインスタンスを保持します。

C++ dll からクラスをエクスポートできないのと同じ理由で、COM オブジェクトをインターフェイスに返す必要があります。

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

この記事は、概念を理解するのに役立ちました。

さて、セルビーは正しいです。インターフェイス名の末尾にある PTR は、インターフェイスへのスマートポインターです。あなたの目的のために、それは本質的に透過的であり、それが単なる ICalc オブジェクトであるかのように扱うことができます。ただし、クリーンアップは自動的に処理されます。ICalcPtr は、バックグラウンドで生成されます。

于 2013-05-05T03:37:33.417 に答える
0

.NET クラスを C++ にエクスポートするためにどのツールを使用したかはわかりませんが、COMLib::ICalPtr は、内部の生のポインターを管理するスマート ポインター クラスの typedef にすぎないと思われます。

デバッガーでステップスルーして、CreateInstance の実装が何をするかを確認しましたか? 最終的に CoCreateInstance と、場合によっては QueryInterface を呼び出す自動生成コードが表示されると思います。Factorial のようなメソッドを IDispatch::Invoke() 呼び出しに変換するためのコードかもしれません。

于 2013-05-05T01:54:46.153 に答える