新手提问:dll引用问题

blankc 2012-12-13 06:05:10
我目前有三个C++编译好的dll文件a.dll/b.dll/c.dll,其中a必须引用b和c,而项目只需要调用a,现在我想把三个dll文件全都放在Debug目录的子目录Device下,请问该如何解决呢?
...全文
293 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
sanae 2012-12-15
  • 打赏
  • 举报
回复
嗯。。俺也学到了延迟加载呢~
blankc 2012-12-15
  • 打赏
  • 举报
回复
嗯,又是一种解决方法,感觉学到了不少
sanae 2012-12-15
  • 打赏
  • 举报
回复
抱歉。。link /lib应该放在所有选项的最前面, /out没关系: 改为这个: link /lib a.lib a1.obj /out:a1.lib 刚才测试了结果手打又打错了……
sanae 2012-12-15
  • 打赏
  • 举报
回复
首先a.dll应该有个a.lib, 然后写一个程序例如a1.cpp,他的一个函数是SetDllDirectory的相关调用 这个时候,从VC命令提示符进去(我不清楚VS的窗口界面的具体操作): 依次编译: 1.cl /c a1.cpp =>得到a1.obj 2.link a.lib a1.obj /lib /out:a1.lib =>得到a1.lib 然后通过a1.lib来使用a.dll就行了
blankc 2012-12-15
  • 打赏
  • 举报
回复
刚刚研究了一下,我找到静态链接的解决方法了,就是在配置属性-链接器-输入-延迟加载的dll里面添加a.dll,这样子应用程序只有在执行到a.dll的函数时才会去搜索它,也就给了我们执行SetDllDirectory的机会了。
blankc 2012-12-15
  • 打赏
  • 举报
回复
动态加载子目录的dll问题解决了!果然是绝对路径的问题,感谢13楼! 既然讨论到这里了,不妨把问题研究更细一点,如果我的dll是通过lib静态链接的,那么应用程序一打开就报错,根本不给我执行 SetDllDirectory 的机会,这样又如何是好呢?毕竟静态加载有头文件可以引用,不需要通过GetProAddress一个一个提取函数。 8楼提到的“让lib在Startup的时候执行SetDllDirectory”的方法又是什么呢?
sanae 2012-12-15
  • 打赏
  • 举报
回复
引用 12 楼 blankc 的回复:
自己顶起来。。。 我觉得这个问题还是有研究价值的,将主目录下的dll分类整理到子目录下一方面可以使目录更加整洁,另一方面又可以避免可能的dll重名冲突。 比如我的项目要用到两个不同的设备,设备开发商提供的开发包里面有两个dll文件重名了,这样我就必须为每个设备新建一个子目录,存放各自的dll文件。 10楼的方法已经试过证明是不可行的,光是DllA就提示找不到,更别提……
注意一下你的当前目录,如果是在VC中运行,用Debug\\Device这个目录,如果不确定,用绝对路径,GetModuleFileName + PathRemoveFileSpec + PathAppend 得到应用程序目录之后加上Device的绝对目录
blankc 2012-12-15
  • 打赏
  • 举报
回复
自己顶起来。。。 我觉得这个问题还是有研究价值的,将主目录下的dll分类整理到子目录下一方面可以使目录更加整洁,另一方面又可以避免可能的dll重名冲突。 比如我的项目要用到两个不同的设备,设备开发商提供的开发包里面有两个dll文件重名了,这样我就必须为每个设备新建一个子目录,存放各自的dll文件。 10楼的方法已经试过证明是不可行的,光是DllA就提示找不到,更别提后续的DllB了。
sanae 2012-12-14
  • 打赏
  • 举报
回复
引用 9 楼 blankc 的回复:
回7楼:我将a/b/c三个dll全部放在子目录Device下面,用LoadLibrary引用a.dll,报错找不到b.dll。只有将b和c放回主目录下面,才能正确执行。我希望b和c不要在主目录下面。
SetDllDirectory("Device");
blankc 2012-12-14
  • 打赏
  • 举报
回复
回7楼:我将a/b/c三个dll全部放在子目录Device下面,用LoadLibrary引用a.dll,报错找不到b.dll。只有将b和c放回主目录下面,才能正确执行。我希望b和c不要在主目录下面。
sanae 2012-12-14
  • 打赏
  • 举报
回复

#define WINVER 0x0502
#include <windows.h>


int main(){
  SetDllDirectory("你的DLL目录"); 
  //Set-在搜索应用程序目录和搜索系统目录之间,搜索这个目录的DLL文件
  //另有AddDllDirectory
  HINSTANCE h = LoadLibrary("a.dll");
  //这个时候载入DLL,如果你的DLL是通过lib“静态”链接的。。好吧。。其实可以有另一个办法让lib在Startup的时候执行SetDllDirectory。。。
  printf("%d\n", h);
}
参考: SetDllDirectory: http://msdn.microsoft.com/ZH-CN/library/windows/desktop/ms686203(v=vs.85).aspx AddDllDirectory: http://msdn.microsoft.com/ZH-CN/library/windows/desktop/hh310513(v=vs.85).aspx
  • 打赏
  • 举报
回复
使用LoadLibrary动态引入 参数填入a.dll的完整路径
blankc 2012-12-14
  • 打赏
  • 举报
回复
楼上误会了,我的意思是程序主目录下面dll太多了,想放在一个子目录底下,这样显得主目录干净清爽多了,不是说只留一个exe。
xumaojun 2012-12-14
  • 打赏
  • 举报
回复
如果是安装的话,可以做成一个安装包,如果是运行的话,用户怎么能要求你只能有一个exe,那这个用户也太那个了吧
blankc 2012-12-14
  • 打赏
  • 举报
回复
顶起来,高手快进来!
blankc 2012-12-14
  • 打赏
  • 举报
回复
回1楼: 全部放在一起当然可以解决,可是dll如果非常多的话,不是显得很乱,用户只需要一个exe文件不是吗? 添加系统Path路径?这是通常的做法吗,我随便点开一个常用软件(比如QQ、Maxthon)的目录,都有看到在他们的子目录下还有各种各样的dll,可是查看系统的Path并没有看到有他们是这么做的? 回2楼:请问具体该如何操作呢?C++连接器选项里面不是应该添加lib文件和路径吗?
漫步者、 2012-12-14
  • 打赏
  • 举报
回复
全部放过去,在你的连接器选项中,添加这个三个dll就行了
赵4老师 2012-12-14
  • 打赏
  • 举报
回复
水至清则无鱼。
枫桦沐阳 2012-12-13
  • 打赏
  • 举报
回复
exe和dll都放在一个地方不就好了,有啥疑问? 如果要求不放在一个地方,那就得在系统的path上加上dll的文件夹路径。

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧