How to resolve '_DllMain@12 already defined in xxx.obj' ?

本文介绍了解决在使用MFC库时遇到的DllMain函数重复定义问题的方法。通过调整项目设置、运行时链接顺序及自定义DllMain函数等手段,可以有效避免链接错误并确保DLL正常工作。

 

    用Visual C++编写DLL,如果在new project时选了MFC DLL,而后又想写成Regular DLL,即拥有自己的DllMain()入口函数,则在build时会遇到类似如下的link错误:

 

1>uafxcwd.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in xxx.obj

 

此种连接错误在用DirectShow + MFC实现filter的时候必然会遇到:

 

"If you try to use MFC framework classes (CWinAapp-, CWnd- derived) in your AX filters, you end up with tons of error messages from the not-initialized MFC framework. To fix this several changes need to be done in the initialization functions (dllentry.cpp)."

 

要解决此类问题,有三种解决方案:

 

1)只需要在工程设置里面,把WIN32,NDEBUG,_WINDOWS,_MBCS,_USRDLL,MSGBOX_EXPORTS,_WINDLL,_AFXDLL中的_USRDLL,删除,就可以正确编译了。

 

2)调整C runtime和MFC runtime的连接顺序,参见:http://support.microsoft.com/default.aspx?scid=kb;en-us;q148652

 

3)http://blog.edu.cn/user3/RFox/archives/2008/2140436.shtml

 

I want to add some initial code in DllMain in a MFC dll project, but after I added the code and compiled, there was a link error:

 

mfcs42d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in DLLMAIN.OBJ

 

DLLMAIN.cpp is the file I created by my own and I define DllMain() in it.

 

What’s the reason? the linker complains that I have a DllMain in DLLMAIN.cpp but there’s another DllMain in mfcs42d.lib.

 

So how to use my own DllMain if a MFC dll project? There’s a quick answer on codeguru , but that article just show the tip without explaining it with more details.

 

The article says, just copy MFC’s dllmodule.cpp into your own project and compile, it will be OK. It seems to be nonsense but after I tried I found it works. But why? By commenting out unnecessary lines, I find these lines are the key point: //(dllmodule.cpp)

 

    // The following symbol used to force inclusion of this module for _USRDLL 

    #ifdef _X86_

    extern “C” { int _afxForceUSRDLL; }

    #else

    extern “C” { int __afxForceUSRDLL; }

    #endif

 

Do you noticed the comment? it forces the inclusion of the module of dllmodule.obj. But how? A searching for _afxForceUSRDLL in MFC source code gives me the answer:

//afx.h

 

    // force inclusion of DLLMODUL.OBJ for _USRDLL

    #ifdef _USRDLL

    #pragma comment(linker, “/include:__afxForceUSRDLL”)

    #endif

 

Again the MFC designer gives us a good comment: “force inclusion of DLLMODUL.OBJ”, OK, got it.

 

Now let summary it up:

    1)When you try to use MFC library, you surely will include afx.h directly or indirectly 

    2)then MFC(afx.h) tell the linker to find the symbol of __afxForceUSRDLL and put that object which contains __afxForceUSRDLL into the program, so linker searches and puts dllmodule.obj into my program, for __afxForceUSRDLL is defined in dllmodule.cpp That’s the common scenario.

 

Then you want to use your own DllMain in a mfc dll project, linker complains that there are two DllMain, one in your code, one in Dllmodule.obj.

 

The solution? Tell the linker to add my dllmain.obj for __afxForceUSRDLL. So we define __afxForceUSRDLL in our own cpp file where our own DllMain is defined, then the linker will ignore mfc’s dllmodule.obj and see only one DllMain and never complains.

 

So the solution is just to add extern “C” { int _afxForceUSRDLL; } in the file where your own DllMain is defined, copying mfc’s dllmodule.cpp is not necessary :-)

 

延伸阅读:

 

1) How to Provide Your Own DllMain in an MFC Regular DLL

http://support.microsoft.com/kb/148791

2) Creating a DLL in DirectShow

http://msdn.microsoft.com/en-us/library/ms899461.aspx

http://msdn.microsoft.com/en-us/library/aa451266.aspx

3) http://www.codeguru.com/cpp/w-p/dll/article.php/c109/

4) DirectShow BaseClasses and MFC

http://blog.monogram.sk/janos/2008/01/10/directshow-baseclasses-and-mfc/

5) http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx

D:\vue_project\e-commerce-visualization> npm run serve > e-commerce-visualization@0.1.0 serve > vue-cli-service serve INFO Starting development server... ERROR Failed to compile with 2 errors 00:12:52 error in ./src/App.vue?vue&type=script&lang=js Module not found: Error: Can't resolve './components/HelloWorld.vue' in 'D:\vue_project\e-commerce-visualization\src' error in ./src/App.vue?vue&type=script&lang=js Module not found: Error: [CaseSensitivePathsPlugin] `D:\vue_project\e-commerce-visualization\src\components\test01.vue` does not match the corresponding path on disk `Test01.vue`. ERROR in ./src/App.vue?vue&type=script&lang=js (./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/App.vue?vue&type=script&lang=js) 1:0-53 Module not found: Error: Can't resolve './components/HelloWorld.vue' in 'D:\vue_project\e-commerce-visualization\src' @ ./src/App.vue?vue&type=script&lang=js 1:0-189 1:0-189 1:190-368 1:190-368 @ ./src/App.vue 2:0-54 3:0-49 3:0-49 8:49-55 @ ./src/main.js 2:0-28 3:10-13 ERROR in ./src/App.vue?vue&type=script&lang=js (./node_modules/babel-loader/lib/index.js??clonedRuleSet-40.use[0]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/App.vue?vue&type=script&lang=js) 2:0-45 Module not found: Error: [CaseSensitivePathsPlugin] `D:\vue_project\e-commerce-visualization\src\components\test01.vue` does not match the corresponding path on disk `Test01.vue`. @ ./src/App.vue?vue&type=script&lang=js 1:0-189 1:0-189 1:190-368 1:190-368 @ ./src/App.vue 2:0-54 3:0-49 3:0-49 8:49-55 @ ./src/main.js 2:0-28 3:10-13 webpack compiled with 2 errors
最新发布
07-09
在 Vue 项目中运行 `npm run serve` 时,如果遇到 **Module not found: Can't resolve 组件路径** 或 **CaseSensitivePathsPlugin 路径不匹配问题**,通常与模块依赖、文件路径大小写或构建工具配置有关。以下是详细的解决方法: ### 1. 检查组件路径是否正确 确保组件导入的路径完全正确,并且区分大小写。例如,在 Unix 系统上,`components/MyComponent.vue` 和 `components/mycomponent.vue` 被视为两个不同的文件。 ```javascript // 正确导入 import MyComponent from '@/components/MyComponent.vue' // 错误导入(路径大小写不匹配) import MyComponent from '@/components/mycomponent.vue' ``` Webpack 的 `CaseSensitivePathsPlugin` 插件会检测路径大小写是否匹配,若不一致则报错 [^4]。 ### 2. 安装缺失的依赖包 如果提示类似 `Module not found: Can't resolve 'vue-router'` 或 `Can't resolve 'fs'`,请确认所需模块是否已安装。 ```bash # 安装 vue-router npm install vue-router # 安装 fs(虽然它是 Node.js 内置模块,但在某些打包工具中需特殊处理) npm install fs ``` 对于 Electron 项目中使用 `fs` 报错的情况,可以在 `webpack.config.js` 中添加以下配置来兼容 Node.js 模块 [^2]: ```javascript module.exports = { // ... resolve: { fallback: { fs: false, path: false } } } ``` ### 3. 清理缓存并重新安装依赖 有时 node_modules 或缓存文件损坏会导致路径解析失败,可以尝试以下步骤清理环境: ```bash # 删除 node_modules 和 package-lock.json rm -rf node_modules package-lock.json # 清除 npm 缓存 npm cache clean --force # 重新安装依赖 npm install ``` ### 4. 检查 Webpack 配置中的别名设置 若使用了路径别名(如 `@` 表示 `src` 目录),请检查 `webpack.config.js` 或 `vue.config.js` 是否正确配置: ```javascript // vue.config.js module.exports = { configureWebpack: { resolve: { alias: { '@': path.resolve(__dirname, 'src') } } } } ``` ### 5. 处理 Windows 与 Linux/macOS 路径差异 在跨平台开发时,Windows 文件系统默认不区分大小写,而 Linux/macOS 是区分的。建议统一使用小写命名组件和路径,以避免因平台差异导致的问题 [^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值