c++ /CLI模板包装器

C++/CLI template wrapper round

本文关键字:包装 CLI c++      更新时间:2023-10-16

我有一组具有相同接口的多个c++类(尽管不是彼此派生的)。我试图包装这些,使它们在。net中可用。

我目前有一个方法,定义包装类使用C/c++ #定义,然后我可以随后实例化类与一行简单的代码

但是我不能调试这个。理想情况下,我希望能够使用通用或模板。然而,我不能在泛型中使用c++类型,这将是解决这个问题的最终方法。

有没有人知道我如何在不使用可怕的宏的情况下做到这一点?

编辑 :

下面是我编写的模板化类的一个例子:
       template< typename CPPResamplerClass >
        ref class TResampler
        {
            CPPResamplerClass*  pResampler;
        public:
            TResampler( int inputSampleRate, int outputSampleRate, int bufferLen ) :
                pResampler( new CPPResamplerClass( inputSampleRate, outputSampleRate, bufferLen ) )
            {
            }
            ~TResampler()
            {
                this->!ResamplerName();
            }
            !TResampler()
            {
                if (pResampler)
                {
                    delete pResampler;
                    pResampler = nullptr;
                }
            }
            property int HistorySize
            {
                int get()
                {
                    return pResampler->HistorySize();
                }
            }
            array< float >^ ResampleAudio(array< float >^ in)
            {
                pResampler->Get
                    array< float >^ out = gcnew array< float >(in->Length);
                cli::pin_ptr< float > pIn = &in[0];
                cli::pin_ptr< float > pOut = &out[0];
                unsigned int inLen = in->Length;
                unsigned int outLen = out->Length;
                if (pResampler->ResampleAudio(pOut, outLen, pIn, inLen))
                {
                    System::Array::Resize(out, outLen);
                    return out;
                }
                return nullptr;
            }
        };
        typedef TResampler< ::Vec::SpeexResample >  SpeexResample;

然后我想从c#访问它,但是SpeexResample不存在。这很可能是因为我使用了一个类型定义…

模板在实例化之前是不存在的。虽然您可以显式地实例化一个:

template ref class TResampler<SomeNativeClass>;

从c#中使用它并不完全是用户友好的。导出的类型将字面上在其名称中有尖括号。祝你好运使用。在c#中,它只能通过反射来实现。

其次是使用派生类型。下面是一个简单的例子:

#include "stdafx.h"
#include <iostream>
namespace CppCli {
    class NativeClassA
    {
        int foo;
    public:
        NativeClassA(int foo) : foo(foo) { std::cout << "Built native class A" << std::endl; }
        int getFoo() const { return foo; }
    };
    class NativeClassB
    {
        int foo;
    public:
        NativeClassB(int foo) : foo(foo) { std::cout << "Built native class B" << std::endl; }
        int getFoo() const { return foo; }
    };
    template<typename NativeClass>
    public ref class ManagedWrapper
    {
        NativeClass* ptr;
    public:
        ManagedWrapper(int foo)
            : ptr(new NativeClass(foo))
        {}
        ~ManagedWrapper()
        {
            this->!ManagedWrapper();
        }
        !ManagedWrapper()
        {
            if (ptr)
            {
                delete ptr;
                ptr = nullptr;
            }
        }
        property int Foo { int get() { return ptr->getFoo(); } }
    };
    public ref class ManagedWrapperA : ManagedWrapper<NativeClassA>
    {
    public:
        ManagedWrapperA(int foo) : ManagedWrapper(foo) {}
    };
    public ref class ManagedWrapperB : ManagedWrapper<NativeClassB>
    {
    public:
        ManagedWrapperB(int foo) : ManagedWrapper(foo) {}
    };
};

可以肯定的是,ManagedWrapperAManagedWrapperB在c#中是可见的。也许您可以宏化这些定义,并且仍然获得不错的调试体验。