//使用的系统是win7 32位英文版,VS2010-sp1英文版。电驴的代码大概是10年10月份下载的。
本作者使用的 win 32位中文字版 vs2010 电驴代码是 2011.5.28 日在电驴官网下载
首先编译所要用的库。
1. error C2440: 'initializing' : cannot convert from 'int' to 'const unsigned char *'。
错误在文件utility(163)中,这个是编译环境提供的文件。这种错误一般是由模板实例化所引起的参数不匹配造成,因该在后面的错误中改正。
错误定位在下面这条语句:
return HashIdentifier(NULL, 0);
引起错误的原因是在map中引入了c++ 0x的新特性,右值引用,而导致的参数演绎后类型不匹配。
修改:
为啥要这样强制转换是因为下面
typedef std::pair<const byte *, unsigned int> HashIdentifier;
(查了一下,最新版的cryplib库可以在Vs2010中编译通过,解决问题的方法和上面的一样)
2. error C2664: 'CryptoPP::AllocatorWithCleanup<T>::AllocatorWithCleanup(const CryptoPP::AllocatorWithCleanup<T> &)' : cannot convert parameter 1 from 'CryptoPP::AllocatorWithCleanup<T>' to 'const CryptoPP::AllocatorWithCleanup<T> &'
这个是由于secblock.h缺少一个类型转换构造函数引起的。查阅了cryptlib的最新版本,发现增加了很多东西。其中有下面语句:
template <class U> struct rebind { typedef AllocatorWithCleanup<U, T_Align16> other; };
#if _MSC_VER >= 1500 //表示编译器版本大于或等于1500
AllocatorWithCleanup() {}
template <class U, bool A> AllocatorWithCleanup(const AllocatorWithCleanup<U, A> &) {}
#endif
上面进行了CryptoPP::AllocatorWithCleanup<CryptoPP::HuffmanDecoder::CodeInfo,0>
到
CryptoPP::AllocatorWithCleanup<std::_Container_proxy,0>
的类型转换。
修改:
在secbolck.h的103行(template <class U> struct rebind { typedef AllocatorWithCleanup<U> other; };)下面增加如下内容:
#if _MSC_VER >= 1500
AllocatorWithCleanup() {}
template <class U, bool A> AllocatorWithCleanup(const AllocatorWithCleanup<U, A> &) {}
#endif
编译。。。
晕,还是不行,看看这次的错误,意思是说给AllocatorWithCleanup模板的参数太多了,比较了一下,确实,新版的cryptlib库中,这个模板有两个参数,旧版的就一个。于是将上面的A参数去掉:变为
ok。
3. 接下来的错误来自两个资源库。其实这个错误很简单,就是特别难找。错误的提示大概如下:
1>I:/Program Files/MSBuild/Microsoft.Cpp/v4.0/Microsoft.CppCommon.targets(113,5): error MSB3073: The command "if not exist ../debug/lang md ../debug/lang
1>I:/Program Files/MSBuild/Microsoft.Cpp/v4.0/Microsoft.CppCommon.targets(113,5): error MSB3073: copy "E:/My Documents/easyMule-VeryCD-src--win7/src/lang/dynamic/languages - Chinese (Taiwan).dll" ../debug/lang/languages - Chinese (Taiwan).dll
1>I:/Program Files/MSBuild/Microsoft.Cpp/v4.0/Microsoft.CppCommon.targets(113,5): error MSB3073:
1>I:/Program Files/MSBuild/Microsoft.Cpp/v4.0/Microsoft.CppCommon.targets(113,5): error MSB3073: :VCEnd" exited with code 1.
经过坚持不懈的搜索搜索在搜索,还是没找到,最后无意中在工程属性页中发现了这个:(如下图)
看到了没,那个if not啥啥啥的。这个动作实在build之后的事件,而出错的原因就是,链接器成功创建了文件,但是现在却找不到了。这个问题我在另一篇日志里讲过,解决方法是将下图中红框中的内容改成zh_TW(如果是大陆语言,则是zh_CH,注意不能在这加后缀dll,不然还是同样的错误):
到现在,lib库编译都没有问题了,不过有个小问题,我始终没找到解决方法。这个问题是这样,就算我不改动代码,每次build(注意,不是rebuild)的时候,都有下列输出:
1>------ Build started: Project: id3lib, Configuration: Debug Win32 ------
2>------ Build started: Project: cryptlib, Configuration: Debug Win32 ------
1>Build started 2011/4/6 21:24:05.
2>Build started 2011/4/6 21:24:05.
2>InitializeBuildStatus:
2> Creating "./Debug/cryptlib.unsuccessfulbuild" because "AlwaysCreate" was specified.
1>InitializeBuildStatus:
1> Creating "./Debug/id3lib.unsuccessfulbuild" because "AlwaysCreate" was specified.
1>ClCompile:
2>CustomBuild:
2> Performing Custom Build Tools
1> All outputs are up-to-date.
1>I:/Program Files/MSBuild/Microsoft.Cpp/v4.0/Microsoft.CppBuild.targets(1151,5): warning MSB8012: TargetPath(E:/My Documents/easyMule-VeryCD-src--win7/id3lib/libprj/./Debug/id3lib.lib) does not match the Library's OutputFile property value (E:/My Documents/easyMule-VeryCD-src--win7/id3lib/libprj/id3libD.lib). This may cause your project to build incorrectly. To correct this, please make sure that $(OutDir), $(TargetName) and $(TargetExt) property values match the value specified in %(Lib.OutputFile).
1>I:/Program Files/MSBuild/Microsoft.Cpp/v4.0/Microsoft.CppBuild.targets(1153,5): warning MSB8012: TargetName(id3lib) does not match the Library's OutputFile property value (id3libD). This may cause your project to build incorrectly. To correct this, please make sure that $(OutDir), $(TargetName) and $(TargetExt) property values match the value specified in %(Lib.OutputFile).
1>Lib:
1> All outputs are up-to-date.
1> id3lib_2005.vcxproj -> E:/My Documents/easyMule-VeryCD-src--win7/id3lib/libprj/./Debug/id3lib.lib
2>ClCompile:
2> All outputs are up-to-date.
1>BscMake:
1> All outputs are up-to-date.
1>FinalizeBuildStatus:
1> Deleting file "./Debug/id3lib.unsuccessfulbuild".
1> Touching "./Debug/id3lib.lastbuildstate".
1>
1>Build succeeded.
1>
1>Time Elapsed 00:00:00.24
2> All outputs are up-to-date.
2> All outputs are up-to-date.
2>Lib:
2> All outputs are up-to-date.
2> cryptlib_2005.vcxproj -> E:/My Documents/easyMule-VeryCD-src--win7/crypto51/crypto/./Debug/cryptlib.lib
2>FinalizeBuildStatus:
2> Deleting file "./Debug/cryptlib.unsuccessfulbuild".
2> Touching "./Debug/cryptlib.lastbuildstate".
2>
2>Build succeeded.
2>
2>Time Elapsed 00:00:00.27
========== Build: 2 succeeded, 0 failed, 9 up-to-date, 0 skipped ==========
有9个库是没有问题的,但是上面两个始终重新编译,这样会造成编译时间延长。。。很不爽啊。
下面就该编译电驴的代码了。这块我碰到2个错误,一个是编译时,一个在链接时。
1. 第一个错误是说:
1>WorkLayer/UPnP/UPnpMgr.cpp(500): error C2662: 'CUPnpNatMappingKey::Serialize' : cannot convert 'this' pointer from 'const CUPnpNatMappingKey' to 'CUPnpNatMappingKey &'
1> Conversion loses qualifiers
uafxcwd.lib(afxglobals.obj) error LNK2005: "public: virtual __thiscall CMemDC::~CMemDC(void)" (??1CMemDC@@UAE@XZ) already defined in ProgressCtrlX.obj
上面是意思是,连接器说,我找到了两个定义,一个在 uafxcwd.lib(afxglobals.obj)里面,还有一个在ProgressCtrlX.obj 。
找了一下,电驴里包含一个MemDC.h文件,里面定义了一个CMemDC类,不巧的是,VS2010的MFC新增了这个类,所以链接时会出问题。
那怎么解决了?有如下办法:
1 修改MFC中CMemDC的名字。这个明显不行。。。
2 将emule中的CMemDC改个名字,这个方法可以,可是我找了下,貌似用这个类的文件还不少。不甘心一条条改,于是想出下面的方法。。。
3 增加一个宏定义,
#define CMemDC XCMemDC
将上面的语句加到stdafx.h的最后。(也可以在工程属性页中以编译器指令的形式定义宏,格式为 /D "CMemDC=XCMemDC")。
经过5天断断续续的找啊改啊,驴子终于跑起来了,至于干不干活就在说吧,哈哈,睡觉!
ps://本人发现的编译问题
- 在编译lib的时候 对于语言包编译是没法解决的。使用他的 zh_CH 删除后续.dll 或者不删除都没法解决,最后解决办法手动将debug下面的zh_CH.dll 移动到
- 在Pinger.h文件里面发现 类型重定义 解决办法修改为
- 找不到头文件 WorkLayer/otherfunctions.cpp(26): fatal error C1083: 无法打开包括文件:“atlrx.h”: No such file or directory 解决办法 在电驴讨论网找到 VS 2008(我的是vs2010)中由于将ALT项目的部分代码剥离出去成为了独立的开源项目,需要用到ALT中正则表达式等功能就需要手动下载。
参考:http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=306398
下载地址:http://www.codeplex.com/AtlServer (http://www.codeplex.com/AtlServer)
把下载的东西解压缩到一个目录,比如c:/alt/
在VS里面[工具]--[选项]--[项目和解决方案]--[VC++目录],在右上角选择[包含引用的文件]中加入c:/alt/include就OK了