Templates CLI/C++;链路错误2028和2019

Templates CLI/C++;链路错误2028和2019,templates,linker,c++-cli,Templates,Linker,C++ Cli,我在从CLI项目传递模板时遇到问题(我认为这就是原因) 我有3层类(出于封装原因和技术原因) 我将展示buggy部件的一个示例(请不要对封装原因发表评论,这里没有演示) 类 > 在C++ dll中: class A { public: template<class T> void foo(T blah) { //Do stuff } } 它们可以编译(.obj已创建),但链接器无法正确链接对象 我得到该方法的2个链接器错误: 错误LNK2028:未解析的令牌 (0A

我在从CLI项目传递模板时遇到问题(我认为这就是原因)

我有3层类(出于封装原因和技术原因)

我将展示buggy部件的一个示例(不要对封装原因发表评论,这里没有演示)

类<强> > <强>在C++ dll中:

class A {
public:
    template<class T>
    void foo(T blah) { //Do stuff }
}
它们可以编译(.obj已创建),但链接器无法正确链接对象

我得到该方法的2个链接器错误:

错误LNK2028:未解析的令牌 (0A000645)“公共:无效uu cdecl” B::foo(类utils::CustomString常量 &,int const&) (??$foo@_N@B@Namespace@@$$FQEAAXAEBVCustomString@utils@@AEB_N@Z) 在函数“private:void”中引用 __clrcall C::foo(int)“($foo@_N@命名空间@@$$FAE$AAMXPE$AAVString@System@@_N@Z)

错误LNK2019:未解析的外部 符号错误LNK2019:未解决 外部符号“公共:无效”\uuuu cdecl B::foo(类int const&)“ ??$foo@_N@B@Namespace@@$$FQEAAXAEBVCustomString@utils@@AEB_N@Z) 在函数“private:void”中引用 __clrcall C::foo(int)“($foo@_N@命名空间@@$$FAE$AAMXPE$AAVString@System@@_N@Z)

编辑

我现在没有这些行(不是在同一台电脑上),但它说它无法链接C.foo中引用的B.foo

我正在调试模式下使用/clr编译ref类/MDd(是的,它必须处于调试模式,因为其他依赖项都以相同的方式编译)

有人知道为什么会这样吗?更重要的是:如何解决这个问题

编辑:

将类B(包装器)设置为使用/GL(整个程序优化)编译时,我得到一个不同的错误:
LNK2001

错误LNK2001:未解决 外部符号“public:bool\uu cdecl 接口::B::foo(int&)const“ (??$foo@_J@B@Namespace@@$$FQEBA_NAEBVCustomString@123@AEA_J@Z)


这些链接器错误指出您缺少某个定义(与声明相反)。无法访问您的代码使我们很难确定这一点,尤其是在没有任何详细链接器错误的情况下

[编辑]

<>这个代码编译和链接在托管C++项目中是很好的:

#pragma managed

class A {
public:
    template<class T>
    void foo(T blah) { int i = 0; }
};

//Class B wraps class A (also regular non-ref class):
class B {
public:
    template<class T>
    void foo(T blah) { a.foo(blah); }
private:
    A a;
};

// Class C is a ref class, which calls class B with an explicit type :
ref class C {
public:
    C() { b = new B(); }
    ~C() {  }
    !C() { delete b; }
    void foo(int blah) { b->foo(blah); }
private:
    B* b;
};
#pragma管理
甲级{
公众:
模板
void foo(T blah){int i=0;}
};
//B类包装A类(也是常规非参考类):
B类{
公众:
模板
void foo(T blah){a.foo(blah);}
私人:
A A;
};
//类C是一个ref类,它使用显式类型调用类B:
参考等级C{
公众:
C(){b=new b();}
~C(){}
!C(){delete b;}
voidfoo(intblah){b->foo(blah);}
私人:
B*B;
};

代码> 这是C++模板的标准损耗,它们没有像.NET泛型那样的外部链接。您必须将模板函数定义放在头文件中,以便将其包含在包含ref类的源代码文件中。就像你的代码片段一样。它不是特定于C++/CLI的

如果编译其余的本机类时没有/clr选项(就像您应该做的那样),请确保将#include与#pragma managed包装在一起。像这样:

#pragma managed(push, off)
#include "FileWithTemplateDefinition.h"
#pragma managed(pop)

问题是visual studio的链接器存在错误

首先,您需要设置/GL(整个程序优化)标志,以便它在编译后链接模板

然后,您需要使用以下解决方法之一:


< /P>什么是记号和外部符号?是的,需要完整的链接错误。对,我没有确切的行,我希望我能帮助我在谷歌上看到很多这样的行,如果我用当前的例子来重构行,这会有帮助吗?当你说“A类是C++ DLL”时,这是否意味着从类B和C中分离出一个单独的DLL?我认为它没有在编译时为正确的类型生成模板代码,但我不知道为什么…嗯,首先,您没有使用模板参数调用foo函数:它不应该是:B.foo(bla)?另外,我也无法让您的代码编译。它告诉我:1>3levelwrapper.cpp(24):错误C4368:无法将“b”定义为托管“C”的成员:不支持混合类型,因此它必须是指向b的指针。@C Johnson,这是指针,抱歉。通常情况下,编译器应该派生变量的类型并创建正确的模板。是的,没有它,它就可以正常工作。有时候我喜欢直言不讳。不,我什么都没做。。。带模板定义的文件在编译时不带/clr。

#pragma managed

class A {
public:
    template<class T>
    void foo(T blah) { int i = 0; }
};

//Class B wraps class A (also regular non-ref class):
class B {
public:
    template<class T>
    void foo(T blah) { a.foo(blah); }
private:
    A a;
};

// Class C is a ref class, which calls class B with an explicit type :
ref class C {
public:
    C() { b = new B(); }
    ~C() {  }
    !C() { delete b; }
    void foo(int blah) { b->foo(blah); }
private:
    B* b;
};
#pragma managed(push, off)
#include "FileWithTemplateDefinition.h"
#pragma managed(pop)