版权声明
:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://jiangliwei.blogbus.com/logs/28509863.html
代码来源:
官方eMule-VeryCD源码包
http://download.verycd.com/eMule-VeryCD-src.rar
编译好的第三方库,来http://www.verycd.com/groups/eMuleDev/209863.topic
http://download.VeryCD.com/emule071112_libsForVS2005.rar
编译环境:WindowsXPsp3CN
VC2008EN + SP1
ATL Server http://www.codeplex.com/AtlServer
修改过程:(只修改error的部分,警告看着不爽自己整)
1. 解压缩源码包,其中src目录下为emule源码。
2. vs2008打开emule.sln,首先是转换工程向导,转换之。
3. 首次build,会提示你如下错误。
1>C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\include\..\src\mfc\afximpl.h(631) : error C2059: syntax error : '<L_TYPE_raw>'
1>C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\include\..\src\mfc\afximpl.h(631) : error C2238: unexpected token(s) preceding ';'
1>C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\include\..\src\mfc\afximpl.h(635) : error C2059: syntax error : '<L_TYPE_raw>'
1>C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\include\..\src\mfc\afximpl.h(635) : error C2238: unexpected token(s) preceding ';'这个错误是由于WINVER定义不正确造成的,编辑stdafx.h,更改代码如下:
#ifndef WINVER
#define WINVER 0x0501
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
4. 重新build,又会有一大坨error,其中最多的是
error C2011: 'tagMENUINFO' : 'struct' type redefinition结构重复定义,查看winuser.h就会发现如下定义
#if(WINVER >= 0x0500)
...
typedef struct tagMENUINFO
{
DWORD cbSize;
DWORD fMask;
DWORD dwStyle;
UINT cyMax;
HBRUSH hbrBack;
DWORD dwContextHelpID;
ULONG_PTR dwMenuData;
} MENUINFO, FAR *LPMENUINFO;
typedef MENUINFO CONST FAR *LPCMENUINFO;
还是WINVER的问题,编辑TitleMenu.h,更改代码如下:
#if (WINVER < 0x0500)
typedef struct tagMENUINFO
{
DWORD cbSize;
DWORD fMask;
DWORD dwStyle;
UINT cyMax;
HBRUSH hbrBack;
DWORD dwContextHelpID;
ULONG_PTR dwMenuData;
} MENUINFO, FAR *LPMENUINFO;
typedef MENUINFO CONST FAR *LPCMENUINFO;
#endif
或者直接注释掉也可以
5. 重新build(很可能你改完了上面的代码后,上一次build仍没有结束,要毫不犹豫地cancel),再次出现一大坨error,总共有两类()
1>.\UPnpNat.cpp(706) : error C2440: '=' : cannot convert from 'const char *' to 'char *'
1>.\SharedFilesCtrl.cpp(585) : error C2039: 'bWin95' : is not a member of 'AUX_DATA'
1> C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\include\..\src\mfc\afximpl.h(54) : see declaration of 'AUX_DATA'
1>SearchListCtrl.cpp
1>.\SearchListCtrl.cpp(1729) : error C2039: 'bWin95' : is not a member of 'AUX_DATA'
1> C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\include\..\src\mfc\afximpl.h(54) : see declaration of 'AUX_DATA'其中第一个很好改,强制转换类型即可。
至于第二种错误,AUX_DATA中已不再包含成员bWin95,如有需要参与运算的部分则bWin95=0,具体请自行google。
这个改起来也很容易,将所有bWin95的部分注释掉即可,其多半是参与if判断,需要的地方统统取FALSE即可。涉及到的文件共有14个
修改举例lf.lfQuality = afxData.bWin95 ? NONANTIALIASED_QUALITY : ANTIALIASED_QUALITY;
改为
lf.lfQuality = ANTIALIASED_QUALITY;
if (!afxData.bWin95 && iItem >= 0)
改为
if (iItem >= 0)
6. 改好之后再次build,出现4条error
>.\EncryptedStreamSocket.cpp(361) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\EncryptedStreamSocket.cpp(492) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\EncryptedStreamSocket.cpp(590) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\Emule.cpp(314) : fatal error C1189: #error : "You are using an MFC version which may require a special version of the above function!"前三条纯粹是写法不正确,变量前面竟然没有写类型,为之一一补充上即可。
第二种是宏警告,意思是VS版本不正确之类的。在其前面的条件中补充上
|| _MFC_VER==0x0900
即可,总共有2处
7. 再次build,这次出现的错误算是比较常见的,不再列举
去掉stdafx.h里的以下几行
#ifndef _USE_32BIT_TIME_T
#define _USE_32BIT_TIME_T
#endif
8. build, 提示link错误
ResizableLib.lib(ResizableDialog.obj) : error LNK2019: unresolved external symbol "public: class CMenu * __thiscall CWnd::GetMenu(void)const " (?GetMenu@CWnd@@QBEPAVCMenu@@XZ) referenced in function "protected: int __thiscall CResizableDialog::OnCreate(struct tagCREATESTRUCTW *)" (?OnCreate@CResizableDialog@@IAEHPAUtagCREATESTRUCTW@@@Z)
ResizableLib.lib(ResizableSheet.obj) : error LNK2001: unresolved external symbol "public: class CMenu * __thiscall CWnd::GetMenu(void)const " (?GetMenu@CWnd@@QBEPAVCMenu@@XZ)
ResizableLib.lib(ResizableSheet.obj) : error LNK2019: unresolved external symbol "public: long __thiscall CWnd::SendMessageW(unsigned int,unsigned int,long)" (?SendMessageW@CWnd@@QAEJIIJ@Z) referenced in function "public: void __thiscall CResizableSheet::RefreshLayout(void)" (?RefreshLayout@CResizableSheet@@QAEXXZ)这里说明一下,emule的源码目录中,其他几个像ResizableLib,crypto51是其所依赖的第三方库,跟emule工程一样需要重新转换并编译。但是为了省事起见,这里直接使用了他人编译好的lib库(在前面有说明)。但是尽管如此,有一部分还是需要重新编译一下的。
需要重新转换并编译ResizableLib这个工程,然后在工程属性里面将Debug和Release的”Chartacter Set“设置为“Use Unicode Character Set”,rebuild之后将生成的ResizableLib.lib分别copy至DebugUnicode和ReleaseUnicode目录(修改工程属性直接生成到这两个目录里也是一样的)。
再次编译emule工程即可通过。
另外需补充一点,VS2008如果没装sp1补丁有一个地方遍不过去,因为懒得查,我就忽略了。
再有,VS2008默认安装时没有包括ATLServer库(现在已开源)的,需要去官方下载,解压后制定inc的路径即可。
至此大功告成,其余的部分请自行研究吧。我也是刚刚开始看emule的源码,因为遍不过去无法调试,很不爽,所以多花了点时间研究一下,如果有什么不正确或需要补充的地方请与我联系。