我有一组具有相同接口的多个C ++类(虽然不是相互派生的)。我试图将它们包装起来,以便在.NET中使用它们。
我目前有一个使用C / C ++ #defines定义包装类的方法,然后我可以用简单的代码行实例化类
但是我无法调试这个。理想情况下,我希望能够使用通用或模板。但是,我不能在泛型中使用C ++类型,这将是解决此问题的最终方法。
有没有人知道如何在不使用可怕的宏的情况下做到这一点?
编辑 :
OK这是我写过的模板化课程的一个例子:
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 ...
答案 0 :(得分: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) {}
};
};
果然,C#可以看到ManagedWrapperA
和ManagedWrapperB
。也许你可以宏这些定义,并且仍然可以获得不错的调试体验。