- 源文件
- base64.cpp
- CWSTAPI.cpp
- IniFile.cpp
- md5.cpp
- 头文件
- base64.h
- CWSTAPI.h
- IniFile.h
- md5.h
其中 CWSTAPI.h 和 CWSTAPI.cpp 文件中包含动态链接库导出函数的声明和定义.
2. 直接生成解决方案会产生如下错误 :
LINK : LNK6004: 没有找到 ..\..\bin/CWSTAPI.dll 或上一个增量链接没有生成它;正在执行完全链接
nafxcwd.lib(dllmodul.obj) : error LNK2005: _DllMain@12 已经在 LIBCMTD.lib(dllmain.obj) 中定义
nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) 已经在 libcpmtd.lib(newop.obj) 中定义
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) 已经在 LIBCMTD.lib(dbgdel.obj) 中定义
nafxcwd.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) 已经在 libcpmtd.lib(newaop.obj) 中定义
nafxcwd.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete[](void *)" (??_V@YAXPAX@Z) 已经在 LIBCMTD.lib(delete2.obj) 中定义
nafxcwd.lib(dllmodul.obj) : warning LNK4006: _DllMain@12 已在 LIBCMTD.lib(dllmain.obj) 中定义;已忽略第二个定义
nafxcwd.lib(afxmem.obj) : warning LNK4006: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) 已在 libcpmtd.lib(newop.obj) 中定义;已忽略第二个定义
nafxcwd.lib(afxmem.obj) : warning LNK4006: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) 已在 LIBCMTD.lib(dbgdel.obj) 中定义;已忽略第二个定义
nafxcwd.lib(afxmem.obj) : warning LNK4006: "void * __cdecl operator new[](unsigned int)" (??_U@YAPAXI@Z) 已在 libcpmtd.lib(newaop.obj) 中定义;已忽略第二个定义
nafxcwd.lib(afxmem.obj) : warning LNK4006: "void __cdecl operator delete[](void *)" (??_V@YAXPAX@Z) 已在 LIBCMTD.lib(delete2.obj) 中定义;已忽略第二个定义
正在创建库 ..\..\bin/CWSTAPI.lib 和对象 ..\..\bin/CWSTAPI.exp
..\..\bin/CWSTAPI.dll : fatal error LNK1169: 找到一个或多个多重定义的符号
后来发现 .cpp 文件的编译顺序如下:
正在编译...
md5.cpp
IniFile.cpp
CWSTAPI.cpp
base64.cpp
3. 以前我没有添加 base64.h 和 base64.cpp 文件, 可以正常编译, 难道是和这个有关, 于是我想办法让 base64.cpp 在 CWSTAPI.cpp 之前编译, 我共想了三种方法 :
(1) 先将 base64.cpp 文件从项目中移除, 接着又加载进来, 那么 "解决方案资源管理器" 中文件的顺序为 :
- 源文件
- CWSTAPI.cpp
- IniFile.cpp
- md5.cpp
- base64.cpp
这样我点击菜单上 生成 -> 重新生成解决方案, 果然编译顺序为 :
正在编译...
base64.cpp
md5.cpp
IniFile.cpp
CWSTAPI.cpp
注意不能使用生成解决方案, 那样可能 .cpp 文件不会重新编译.
但是这样会发生问题, 因为你关掉这个解决方案, 重新打开这个解决方案时, 文件又按字母顺序在 "解决方案资源管理器" 中显示, 这就以为着生成解决方案编译 .cpp 文件时是按照 .cpp 文件的字母顺序来编译的.
(2) 重命名 .cpp 文件的名称
既然 .cpp 文件是根据字母顺序排序的, 编译时也遵循这个顺序的反序, 那么只要保证 CWSTAPI.cpp 文件最后编译就可以了, 而 base64.cpp 文件排在 CWSTAPI.cpp 文件的前面, 那么将 base64.cpp 文件重命名为 ZBase64.cpp, 并相应地将 base64.h 重命名为 ZBase64.h, 这样就改变了编译的顺序. 这样做有个不好的地方就是为了达到调整编译顺序的目的而去改变 .cpp 文件的名称, 这样的命名往往是违心的.
(3) 将 .cpp 移到其他文件夹中
VC 默认将 .cpp 文件放在 源文件中, 将 .h 文件放在 头文件中.
建立一个文件夹 Include, 将除了 CWSTAPI.h, CWSTAPI.cpp 文件的所有 .h 和 .cpp 文件都放在这个文件夹中, 即
- 源文件
- CWSTAPI.cpp
- 头文件
- CWSTAPI.h
- 资源文件
- Include
- base64.cpp
- base64.h
- IniFile.cpp
- IniFile.h
- md5.cpp
- md5.h
这个顺序需要重新打开解决方案才能看到, 这样编译顺序为 :
正在编译...
md5.cpp
IniFile.cpp
base64.cpp
CWSTAPI.cpp
4. 这个问题足足困扰了我大半天, 最后终于找到这几种解决方法, 并且分享给大家, 最终我采用了最后一种方法. 这些方法肯定不是最好的, 所以我想征集一下大家的方法.
16 个解决方案
#1
顶楼主
#2
我基本上也是换文件名、位置,希望找到更好的方法。
UP.
UP.
#3
up
#4
up
#5
顶
#6
怎么加分啊?
#7
重命名
顶下先
有点累了
先 沙发一会~~~~~~~~~~~~~~·
顶下先
有点累了
先 沙发一会~~~~~~~~~~~~~~·
#8
先告诉你怎么加分,再看题,第二天可以给帖子加分,并且限制只能加100分
#9
解决了问题就行,如果是我,我首先想到的肯定是第2种解决办法,不过我倾向于最后一种解决办法
#10
赞!
#11
写得太多,没看仔细.我刚遇到过类似问题.链接时出错,再链接一遍.就可以.原因是在".h"中定义全局变量引起的.将这个全局变量放到类中.好像用extern也可以.
#12
第一次发帖, 给大家都送分啊.
#13
mark
#14
还有一个,如果在ocx工程中使用CString也会触发2005错误,只能使用其他类型
#15
狂顶楼主。太有才了。这个问题困扰我了很久,调单线程为多线程,也不能解决。一试楼主的方法,立竿见影。很好。希望大家也都多留意其他解决办法,都分享一下。
#16
直接修改.vcproj,把base64.cpp和base64.h放最后面,就好了,我的老天。
#1
顶楼主
#2
我基本上也是换文件名、位置,希望找到更好的方法。
UP.
UP.
#3
up
#4
up
#5
顶
#6
怎么加分啊?
#7
重命名
顶下先
有点累了
先 沙发一会~~~~~~~~~~~~~~·
顶下先
有点累了
先 沙发一会~~~~~~~~~~~~~~·
#8
先告诉你怎么加分,再看题,第二天可以给帖子加分,并且限制只能加100分
#9
解决了问题就行,如果是我,我首先想到的肯定是第2种解决办法,不过我倾向于最后一种解决办法
#10
赞!
#11
写得太多,没看仔细.我刚遇到过类似问题.链接时出错,再链接一遍.就可以.原因是在".h"中定义全局变量引起的.将这个全局变量放到类中.好像用extern也可以.
#12
第一次发帖, 给大家都送分啊.
#13
mark
#14
还有一个,如果在ocx工程中使用CString也会触发2005错误,只能使用其他类型
#15
狂顶楼主。太有才了。这个问题困扰我了很久,调单线程为多线程,也不能解决。一试楼主的方法,立竿见影。很好。希望大家也都多留意其他解决办法,都分享一下。
#16
直接修改.vcproj,把base64.cpp和base64.h放最后面,就好了,我的老天。