之前虽然经常使用dll和Lib,,但却没有亲身尝试生成,对于格式和流程不是很清楚,借机学习了一下。 参考和查阅了很多帖子,比如 http://blog.csdn.net/yanbdsky/article/details/4587813 http://topic.csdn.net/u/20100727/11/13a60518-7710-44a0-857e-cadd12da7524.html。 还有很多类似的,总之大致就两种思路,虽然我不知道两种在具体实现上有什么异同,现将他们过程介绍一下。 介绍之前,简要说明一下我的需求和背景,手上的这个项目是基于MFC的一个对话框工程,框架很简单,其中大量引用和调用VTK和OpenCV的函数,还有一些控件操作,屏幕交互,计算分析等。最终希望生成一个dll,提供一个函数接口,调用该函数弹出设计的对话框程序,之所以没有一开始就采用dll,主要是因为对方的需求突然有变。 方案一:新建一个DLL工程,比如MyDLL,将原工程中的*.h 和 *.cpp文件复制到新建的工程目录下,并添加到工程中。同样的方式导入res文件,不用再去建一遍对话框。我的做法是,新建的工程和原工程同名,然后仅在MyDLL.h中添加相应的头文件,最关键的一步是添加dll函数接口: 在MyDLL.h中添加 extern 'C' __declspec(dllexport) void ShowDentalViewDlg(void);// 'C'很必要,多个教程中强调,不加的话,由于C++编译器为函数添加类型名,可能导致在其他程序中调用无法找到对应的函数 然后在MyDLL.cpp中实现它: extern 'C' __declspec(dllexport) void ShowDentalViewDlg(void) CDentalViewDlg dlg; } 不用多解释,CDentalViewDlg 就是我想调出的对话框类。 编译后可以再debug文件夹下找到对应工程的dll和lib文件。 然后可能你会说之后就是调用了啊,我原来也是这么做的,但是这却让我绕了很大的圈,调用失败后只是一味地怀疑这种方法无效,去忽略了一个非常关键的问题,我生成的dll和lib参考完整吗?很多人压根就不会想到之前exe下没问题的程序,生成dll和lib怎么会有参考不完整问题呢?这个问题我遇到了,虽然我不知道为什么。下面说说如何检查生成的dll的参考完整性。 我用的是VC自带的工具depends.exe, 很简单,打开dll文件后,可以看到其参考的dll还有其接口函数。我发现之所以我生成的dll和lib在测试程序中调用失败,是因为生成的dll中参考dll中有黄颜色的不完整项,因为我大量调用VTK和Opencv,而它们又调用很多其他的库,最终缺少msvcr80.dll和msvcp80.dll,解决办法自然是添加这两个dll了,好不容易找到了,我不知道原先exe下是怎么找到它们的,因为在系统盘中好像我没有发现这两个文件的踪迹。看到黄色dll都没了,心里好不欣慰。 生成完整的dll和lib 后,最后一步就是测试了,这一步只要按部就班就好了。首先将lib和dll拷贝到测试工程中,添加它们的路径(这一步有多种方式:可以像添加VTk库一样,也可以用#pragma comment(lib,'***'))。不要忘了最重要的一步,拷贝并添加所有dll中用到的*.h文件到测试程序。最后为测试控件添加响应函数: void CTestDLLDlg::OnBnClickedButton1() } 这样就可以编译、测试了。
第二种方案 直接在原工程中修改配置,在 项目/项目属性/配置属性/常规/配置类型中将.exe改为dll,添加接口函数(在项目的.h中声明在.cpp中定义): extern 'C' void show() AFX_MANAGE_STATE(AfxGetStaticModuleState()); dlg->DoModal(); 然后编译,这次可以看到在debug文件夹中相比方案一少了.lib文件。 其调用方式也不太一样: void CTestDLLDlg::OnBnClickedButton1() typedef void (*Msgs)(void); HINSTANCE h = ::LoadLibrary(L'DentalView.dll'); if (h == NULL) return;
dllfun(); ::FreeLibrary(h); } 这里要注意,如前面参考网页所述,需将工程的.cpp中的InitInstance()函数中调用dlg.DoModel()相关语句注释掉,以便其不在导入dll时就弹出对话框。 但这个方法我遇到一个问题,LoadLibrary(L'DentalView.dll')返回值总是为null,目前还在测试,有待进一步补充。
以上就是自己对MFC 的exe转dll的尝试和学习心得,有其他方法的欢迎补充。 |
|
来自: Kenshin0_0 > 《待分类》