如何在C++/CLI中封装C++接口(抽象类)

本文关键字:C++ 接口 抽象类 封装 CLI | 更新日期: 2023-09-27 18:00:32

我有一些C++代码:

namespace Compute {   
  class __declspec(dllexport) IProgressCB {   
  public:     
    virtual void progress(int percentCompleted) = 0;   
  };    
  double __declspec(dllexport) compute(IProgressCB *progressCB, ...); 
}

我需要从C#调用
因此,我想将这段C++代码封装在C++/CLI中。

我了解如何包装compute()函数,但是如何包装IProgress接口?

(.Net类似乎不可能继承C++类?)

如何在C++/CLI中封装C++接口(抽象类)

使用一个ref class,它保存一个指向包装实例的指针:

namespace ComputeCLI {
    public ref class IProgressCB{
    public:
        void progress(int percentCompleted)
        {
            // call corresponding function of the wrapped object
            m_wrappedObject->progress(percentCompleted);
        }
    internal:
       // Create the wrapper and assign the wrapped object
       IProgressCB(Compute::IProgressCB* wrappedObject) 
            : m_wrappedObject(wrappedObject){}
        // The wrapped object
        Compute::IProgressCB* m_wrappedObject;
    };
    public ref class StaticFunctions{
    public:
        static double compute(IProgressCB^ progressCB, ...){
            Compute::compute(progressCB->m_wrappedObject, ...);
        }
    };
}

这个框架应该让你开始:

interface class IProgressEventSink
{ ... };
class ProgressEventForwarder : IProgressEventCB
{
    gcroot<IProgressEventSink^> m_sink;
public:
    ProgressEventForwarder(IProgressEventSink^ sink) : m_sink(sink) {}
// IProgressEventCB implementation
    virtual void OnProgress( ProgressInfo info ) { m_sink->OnProgress(info.a, info.b); }
};
ref class ComputeCLI
{
     Compute* m_pimpl;
 // ...
public:
     RegisterHandler( IProgressEventSink^ sink )
     {
         // assumes Compute deletes the handler when done
         // if not, keep this pointer and delete later to avoid memory leak
         m_pimpl->RegisterHandler(new ProgressEventForwarder(sink));
     }
};