Templates CLI/C++;链路错误2028和2019
我在从CLI项目传递模板时遇到问题(我认为这就是原因) 我有3层类(出于封装原因和技术原因) 我将展示buggy部件的一个示例(请不要对封装原因发表评论,这里没有演示)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
类<强> > <强>在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)