C ++链接器问题,内联模板方法 [英] C++ linker problem, inline template method

查看:79
本文介绍了C ++链接器问题,内联模板方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hello Everyone!



我对旧项目有疑问,他们希望我在Visual Studio中编译。这个应用程序在QtCreator中使用gcc编译器,但在VS10中使用Qt实现它有一些编译错误。链接器在dll中找不到方法。这是来自有问题的课程的样本:



Hello Everyone!

I have a problem with an old project, that they want me to compile in Visual Studio. This application was working in QtCreator with gcc compiler, but while in VS10 with Qt implementation it has some compile errors. The linker doesn't find the methods in the dll. This is a sample from the problematic classes:

template <class SW> //SettingsWidget
class RCC_EXPORT_IMPORT SettingsWidgetList : public ObjectList<SW>
{
    public:
        inline RCC::Result apply()
        {
            bool isOk=true;
            for(int i=0, l=ObjectList<SW>::count(); i < l; ++i)
            {
                if(!rcc_resultToBool((*this)[i]->apply()))
                    isOk=false;
            }
            return rcc_boolToResult(isOk);
        }
};







这是来自dll的公共标题。

...并且链接器告诉:






This is from the dll's public header.
...and the linker tells this:

Error   794 error LNK2019: unresolved external symbol "__declspec(dllimport) public: enum ReworkClient::RCC::Result __thiscall ReworkClient::SettingsWidgetList<class ReworkClient::ProfileSettingsWidget>::apply(void)" (__imp_?apply@?$SettingsWidgetList@VProfileSettingsWidget@ReworkClient@@@ReworkClient@@QAE?AW4Result@RCC@2@XZ) referenced in function "private: void __thiscall ProfileDialog::on_OkButton_clicked(void)" (?on_OkButton_clicked@ProfileDialog@@AAEXXZ) C:\!projects\c++\ReworkClient\2.0.x\ReworkClient\rcprofile.obj  ReworkClient



看来问题与apply()方法有关,但我不明白它们之间有什么区别VS和gcc编译器工作。任何人都知道apply方法的声明有什么不对吗?

欢迎任何想法(甚至批评)!我没有线索...



感谢您的阅读!

问候

Adam


It seems the problem with the apply() method, but I don't understand what can be the difference between the VS and gcc compilers working. Anyone has any idea what can be wrong with the apply method's declaration?
Any idea are welcomed (even critiques)! Im out of clues...

Thank you for reading!
Regards
Adam

推荐答案

SettingsWidgetList @ VProfileSettingsWidget @ReworkClient @@@ ReworkClient @@ QAE?AW4Result @ RCC @ 2 @XZ)在函数private:void __thiscall ProfileDialog :: on_OkButton_clicked(void)中引用(?on_OkButton_clicked @ ProfileDialog @@ AAEXXZ)C:\!projects \ c ++ \ReworkClient \2.0.x\ReworkClient\rcprofile.obj ReworkClient
SettingsWidgetList@VProfileSettingsWidget@ReworkClient@@@ReworkClient@@QAE?AW4Result@RCC@2@XZ) referenced in function "private: void __thiscall ProfileDialog::on_OkButton_clicked(void)" (?on_OkButton_clicked@ProfileDialog@@AAEXXZ) C:\!projects\c++\ReworkClient\2.0.x\ReworkClient\rcprofile.obj ReworkClient



看来apply()方法存在问题,但我不明白VS和gcc编译器之间的区别是什么。任何人都知道apply方法的声明有什么不对吗?

欢迎任何想法(甚至批评)!我没有线索...



感谢您的阅读!

问候

Adam


It seems the problem with the apply() method, but I don't understand what can be the difference between the VS and gcc compilers working. Anyone has any idea what can be wrong with the apply method's declaration?
Any idea are welcomed (even critiques)! Im out of clues...

Thank you for reading!
Regards
Adam


您的 SettingsWidgetList 类是一个模板类,因此编译器在您使用具体模板参数实现其对象时生成代码。编译DLL时,可能无需在库代码中实例化任何此类对象。因此编译器不会在您的DLL中生成成员函数。



但是,在您的客户端代码中,您实例化一个类型为 SettingsWidgetList<的对象; profilesettingswidget>< / profilesettingswidget> ,这是编译器在创建DLL时未见到的。因此它无法在DLL中找到 apply 方法。



如果ProfileSettingsWidget是您想要的唯一模板参数要用于 SettingsWidgetList 类,可以强制编译器通过实例化类型的对象来生成所需的代码。您的DLL代码中的SettingsWidgetList< profilesettingswidget>< / profilesettingswidget>



但是,一般情况下,DLL和模板类的概念是有点相互排斥。模板类通常只由定义它的头文件分发,而不是通过DLL的预编译代码分发。
Your SettingsWidgetList class is a template class and hence the compiler generates code for it at the moment you instanciate an object of it with a concrete template parameter. When you compiled your DLL, there probably was no need to instantiate any such object in your library code. And hence the compiler did not produce the member functions in your DLL.

In your client code, however, you instantiate an object of type SettingsWidgetList<profilesettingswidget></profilesettingswidget>, something the compiler has not seen, when you created the DLL. Hence it cannot find the apply method in the DLL.

If ProfileSettingsWidget is the only template parameter that you intend to use for the SettingsWidgetList class, you can force the compiler to generate the required code by
instantiating an object of type SettingsWidgetList<profilesettingswidget></profilesettingswidget> in your DLL code.

In general, however, the concepts of DLLs and template classes are somewhat excluding each other. A template class is usually distributed just by the header file that defines it and not via precompiled code of a DLL.


我怀疑DLL的导出可能是标准的C样式,但是你生成的代码是C ++。您需要在QT标题周围使用以下构造。

I suspect it may be that the DLL's exports are standard C style, but the code you are generating is C++. You need to use the following construct around the QT headers.
extern "C"{
// QT includes go here
}



参见 http://msdn.microsoft.com/en-us/library/0603949d.aspx [ ^ ]以获取完整描述。


See http://msdn.microsoft.com/en-us/library/0603949d.aspx[^] for a full description.


这篇关于C ++链接器问题,内联模板方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆