0

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

这是托管功能:

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 参数函数)
4

1 回答 1

1

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

您可以查看将 C++ 模板函数定义存储在 .CPP 文件中提供的示例

正如他所说,您可以执行以下操作(复制粘贴警报):

.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&);
于 2012-12-14T02:03:17.887 回答