C ++模板函数调用托管函数

时间:2012-12-14 01:31:42

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

我正在尝试围绕托管类构建一个包装器,以便我可以从本机代码中调用它。

以下是托管功能:

void MyManagedFunction(MyStruct iStruct)
{
  // Code according to what are the types of the 2 MyStruct members
}

struct MyStruct
{
  public MyStruct(Object iValue1, Object iValue2) : this()
  {
    Value1 = iValue1; // Often contains DateTime::Now
    Value2 = iValue2;
  }

  public Object Value1;
  public Object Value2;
}

在我的例子中,Value1几乎总是System :: DateTime :: Now,而Value2几乎总是一个常见的数据类型(int,double,float,string,bool)。我想在包装器中制作两个模板化函数。

在包装器中.h我有以下内容:

#ifdef MYWRAPPER_EXPORTS
#  define MYWRAPPER  __declspec(dllexport)
#else
#  define MYWRAPPER  __declspec(dllimport)
#endif  

class MYWRAPPER MyWrapper
{

public:
  MyWrapper();
  ~MyWrapper();

  template <class T> void MyNativeFunction(T iParam1)
  {
    MyStruct^ wStruct = gcnew MyStruct(System::DateTime::Now, iParam1);
    //The class containing the managed function is a singleton
    MyManagedClass::Instance->MyManagedFunction(wStruct); 
  }

  template <class T, class W> void MyNativeFunction(T iParam1, W iParam2)
  {
    MyStruct^ wStruct = gcnew MyStruct(iParam1, iParam2);
    //The class containing the managed function is a singleton
    MyManagedClass::Instance->MyManagedFunction(wStruct);
  }
};

这个包装器编译没有问题。当我在纯粹的本机代码中包含.h时,问题显然出现了。由于我无法隐藏模板化函数的内容,因此我在本机端可以看到可以防止本机代码编译的内容。

我想知道是否有解决方法来实现这一目标。我不介意我是否仅限于使用原始类型作为函数的参数。最好的办法是,如果我能够简单地隐藏本机代码中模板化函数的内容,那么它只知道签名

这是我到目前为止所尝试/考虑的内容:

  • 将参数转换为void *并调用一个函数,在该函数中调用托管函数。通过这样做,我无法将void *转换回对象,因为我丢失了它的类型并且使用typeid来获取'T'或'W'类型没有帮助,因为它从编译器到另一个不同。
  • 为我想要使用的每种类型重载函数。如果我找不到更好的解决方案,这就是我最有可能使用的。问题是它意味着很多过载(特别是考虑到组合数量的2个参数)

1 个答案:

答案 0 :(得分:1)

如果您知道模板将采用的所有类型,则可以强制使用这些变量对其进行实例化,从而将模板函数的代码放在源文件中而不是标头中。

您可以查看Storing C++ template function definitions in a .CPP file

中提供的示例

正如他所说,你可以这样做(复制粘贴警报):

.h文件

class foo
{
public:
    template <typename T>
    void do(const T& t);
};

.cpp文件

template <typename T>
void foo::do(const T& t)
{
    // Do something with t
}

template void foo::do<int>(const int&);
template void foo::do<std::string>(const std::string&);