【问题标题】:C++/CLI template wrapper roundC++/CLI 模板包装轮
【发布时间】:2016-09-16 13:20:58
【问题描述】:

我有一组具有相同接口的多个 C++ 类(虽然不是从彼此派生的)。我正在尝试包装这些以使它们在.NET 中可用。

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

但是我无法调试它。理想情况下,我希望能够使用通用或模板。但是我不能在泛型中使用 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 不存在。这很可能是因为我使用的是 typedef ...

【问题讨论】:

  • 这个问题肯定需要一些示例代码。作为高级用户,您应该知道minimal reproducible example 是什么...
  • 模板是 C++ 细节,对任何其他 .NET 语言都没有用处。请改用generic 关键字。
  • @HansPassant:但我不能使用 C++ 类型作为泛型类的参数……可以吗?如果可以的话..你能解释一下,因为那是我问题的症结所在! ;)
  • 您可以使用工厂模式并通过符合 cls 的接口类调用您的 C++ 模板类。
  • Hmya,这里的核心问题是您的代码根本不是通用的。当 C# 代码请求 TResampler&lt;int&gt;TResampler` 时,您无能为力。还有一百万种。您将不得不将其淘汰,并且仅公开可以有意义使用的那些。应该是一个合理的短名单。

标签: c++ templates generics c++-cli


【解决方案1】:

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

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# 中是可见的。也许您可以宏这些定义,仍然可以获得不错的调试体验。

【讨论】:

  • 感谢您的回复,我没有发现它到了,正在做其他事情。我会看看我是否能让这个工作。目前它给了我一个编译器堆栈溢出,但它看起来很有希望。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-23
  • 2013-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多