刚在CSDN上问了个问题,记录之,模板,DLL,这些都是难以处理好的东西啊,尤其是模板,正是又爱又恨,最后不想用,又不得不用。
原帖地址为:
http://community.csdn.net/Expert/TopicView3.asp?id=5432653
下载log4cplus-1.0.2.tar.gz,(注意,不是最新的1.0.3)。解压在vs2005中打开
/log4cplus-1.0.2/msvc6/log4cplus.dsw,并转换为vs2005工程,在debug模式中编译其中的log4cplus_dll工程,可能出现编译错误出现在/log4cplus-1.0.2/src/stringhelper.cxx中,将此文件出错的位置也就是128行左右的__value改名,例如改成__rvalue,然后在118行处添加代码:
typedef std::output_iterator_tag iterator_category;
即可通过编译。
注意:如在在unicode环境下使用log4cplus,则需要先将log4cplus在unicode下编译出lib,在使用时可以用以下方式:
- wchar_t *tmp = L"test";
- Logger logger1 = Logger::getInstance(tmp);
然后在debug模式下编译其他工程如appender_test,可能出现缺少dll错误,将log4cplusd.dll拷贝至工作路径比如/log4cplus-1.0.2/msvc6/tests/appender_test_Debug
下即可运行。直接按F5可能出现编译错是因为thread_test工程编译无法通过。不过继续运行即可,并不影响其他工程运行。单独编译thread_test工程会出现如下错误:
1. main.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: class TestThread * __thiscall log4cplus::helpers::SharedObjectPtr <class TestThread> ::operator-> (void)const " (__imp_??C?$SharedObjectPtr@VTestThread@@@helpers@log4cplus@@QBEPAVTestThread@@XZ),该符号在函数 _main 中被引用
2. main.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: void __thiscall log4cplus::helpers::SharedObjectPtr <class TestThread> ::`default constructor closure '(void) " (__imp_??_F?$SharedObjectPtr@VTestThread@@@helpers@log4cplus@@QAEXXZ),该符号在函数 _main 中被引用
3. main.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __thiscall log4cplus::helpers::SharedObjectPtr <class TestThread> ::~SharedObjectPtr <class TestThread> (void) " (__imp_??1?$SharedObjectPtr@VTestThread@@@helpers@log4cplus@@QAE@XZ),该符号在函数 _main 中被引用
./thread_test_Release/thread_test.exe : fatal error LNK1120: 3 个无法解析的外部命令
于是去thread_test工程下,里面就一个main.cxx
主要就是这一句:
第83行,
log4cplus::helpers::SharedObjectPtr <TestThread> threads[NUM_THREADS];
这里无法找到,再看生成的dll文件呢,于是dumpbin一下,发现其导出是这样的。
7 6 0001CD30 ??0?$SharedObjectPtr@VAbstractThread@thread@log4cplus@@@helpers@log4cplus@@QAE@PAVAbstractThread@thread@2@@Z
怎么会这样呢?
而且经过实验,发现VC6编译能够通过,但是通过dumpbin观察,其导出函数与VS2005很不同。
继续google,找到一位和我问题差不多的
http://www.eggheadcafe.com/forumarchives/vclanguage/Aug2005/post23130691.asp
看来就是因为模板不是real code,所以dll无法根据实际情况导出,这里的class TestThread只有exe知道,所以link的时候找不到,因为没有生成嘛。而VC6,是像这句话所说
Some compilers such as VC6 assume that all template code must have all possible instantiations in the ?translation unit that it is declared in, but there 's no real justification
现在我的问题就是,如何做,使得这个代码可以编译通过呢?
还是因为C++本身的语法条件局限,根本就是一个无法解决的问题呢?
多谢多谢!
PS:贪心贪心,还想问问,除了log4cplus外,是否有其他log类。
已试用log4cpp,但是似乎工程都不全,有很多.vcproject都没有,就没有搞。而且也很旧了,是2005年的。
至于log4cxx,下载的0.9.7,看介绍说有不少bug,而0.9.8因为要大改还是啥的,还没出来。
有无其他推荐?
关于这个问题的解决办法可以参考http://topic.csdn.net/u/20070331/10/7c5c90a5-565f-40a1-9100-6c81b39346e8.html
不过也没有给出比较好的解决方案。