Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;调用托管函数的模板化函数_C++_Templates_C++ Cli - Fatal编程技术网

C++ C++;调用托管函数的模板化函数

C++ C++;调用托管函数的模板化函数,c++,templates,c++-cli,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 = iVal

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

以下是托管功能:

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);
  }
};
\ifdef MYWRAPPER\u导出
#定义MYWRAPPER\uuu declspec(dllexport)
#否则
#定义MYWRAPPER\uu declspec(dllimport)
#恩迪夫
类MYWRAPPER MYWRAPPER
{
公众:
MyWrapper();
~MyWrapper();
模板无效MyNativeFunction(T iParam1)
{
MyStruct ^wStruct=gcnewmystruct(System::DateTime::Now,iParam1);
//包含托管函数的类是单例
MyManagedClass::Instance->MyManagedFunction(WSStruct);
}
模板无效MyNativeFunction(T iParam1,W iParam2)
{
MyStruct ^wStruct=gcnewmystruct(iParam1,iParam2);
//包含托管函数的类是单例
MyManagedClass::Instance->MyManagedFunction(WSStruct);
}
};
这个包装器编译没有问题。当我在纯本机代码中包含.h时,问题显然就出现了。因为我不能隐藏模板函数的内容,所以我管理了本机端可见的东西,这些东西阻止了本机代码的编译

我想知道是否有一个解决办法,以实现这一点。我不介意我被限制只使用基本类型作为函数的参数。最好的情况是,如果我能够简单地将模板函数的内容隐藏在本机代码中,那么它只知道签名

以下是我迄今为止所尝试/考虑的:

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

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

您可以查看中提供的示例

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

.h文件

class foo
{
public:
    template <typename T>
    void do(const T& t);
};
class-foo
{
公众:
模板
无效do(常数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&);
模板
void foo::do(常量T&T)
{
//用t做点什么
}
模板void foo::do(const int&);
模板void foo::do(const std::string&);

在std::string或其他复杂类型的情况下使用这种重载方法基本上解决了这个问题。但是,如果我没有在cpp中专门化一个类型(比如double),然后尝试使用该类型调用函数,我会得到一个不清楚的错误。是否有方法断言所用类型的规范存在,如果没有,则指定要显示的错误?我尝试使用:static_assert(sizeof(T)!=sizeof(T),“未找到专门化”);然而,在主函数中,它每次都会出现,即使所使用的类型是正确的。嗯,最后似乎连您的解决方案都不起作用。它仍然给我链接错误。我试过使用我能找到的最基本的函数(模板void func();),但这个事件不起作用。我想我没有其他选择,只能使用带有特定参数类型的重载。我很惊讶它不起作用。只要您声明了所有将要使用的类型,它就应该可以工作。不知道为什么。我想知道这是否与我在CLI中执行此操作有关。无论如何,我已经完成了函数重载的使用。通过使用宏,我可以使它变得足够简单。明天我会试着发布我的解决方案