(1)MFC调用DLL基本步骤
win32 dll和mfc dll
现在最常看见的关于DLL的问题就是如何在DLL中使用对话框,这是一个很普遍的关于如何在DLL中使用资源的问题。
这里我们从Win32 DLL和MFC DLL两个方面来分析并解决这个问题。
1.Win32 DLL在Win32 DLL中使用对话框很简单,你只需要在你的DLL中添加对话框资源,而且可以在对话框上面设置你所需要的控件。
然后使用DialogBox或者CreateDialog这两个函数(或相同作用的其它函数)来创建对话框,并定义你自己的对话框回调函数处理对话框收到的消息。
下面通过一个具体实例来学习如何在Win32 DLL中使用对话框,可以按照以下步骤来完成这个例子:1)在VC菜单中File->New新建一个命名为UseDlg的Win32 Dynamic-Link Library工程,下一步选择A simple DLL project。
2)在VC菜单中Insert->Resource添加一个ID为IDD_DLG_SHOW的Dialog资源,将此Dialog上的Cancel 按钮去掉,仅保留OK按钮。
再添加一个ID为IDD_ABOUTBOX的对话框,其Caption为About。
保存此资源,将资源文件命名为UseDlg.rc。
并将resource.h和UseDlg.rc加入到工程里面。
3)在UseDlg.app中包含resource.h,并添加如下代码:HINSTANCE hinst = NULL;HWND hwndDLG = NULL;BOOL CALLBACK DlgProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam);BOOL CALLBACK AboutProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam);extern "C" __declspec(dllexport) void ShowDlg();BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved){switch(ul_reason_for_call){case DLL_PROCESS_ATTACH:hinst = (HINSTANCE)hModule;case DLL_PROCESS_DETACH:break;}return TRUE;}extern "C" __declspec(dllexport) void ShowDlg(){hwndDLG = CreateDialog(hinst,MAKEINTRESOURCE(IDD_DLG_SHOW), NULL,(DLGPROC)DlgProc);ShowWindow(hwndDLG, SW_SHOW);}BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam){switch(message){case WM_INITDIALOG:return TRUE;case WM_COMMAND:if(LOWORD(wParam)==IDOK)DialogBox(hinst,MAKEINTRESOURCE(IDD_ABOUTBOX),hDlg,(DLGPROC)AboutProc);return TRUE;case WM_CLOSE:DestroyWindow(hDlg);hwndDLG = NULL;return TRUE;}return FALSE;}BOOL CALLBACK AboutProc(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam){switch(message){case WM_CLOSE:EndDialog(hDlg,NULL);hwndDLG = NULL;return TRUE;}return FALSE;}4)编译生成UseDlg.dll和UseDlg.lib。
C_中如何调用动态链接库DLL
C#中如何调用动态链接库DLL编程技术2009-08-06 08:58:48 阅读863 评论0 字号:大中小动态链接库(也称为DLL,即为“Dynamic Link Library”的缩写)是Microsoft Windows最重要的组成要素之一,打开Windows系统文件夹,你会发现文件夹中有很多DLL文件,Windows就是将一些主要的系统功能以DLL模块的形式实现。
动态链接库是不能直接执行的,也不能接收消息,它只是一个独立的文件,其中包含能被程序或其它DLL调用来完成一定操作的函数(方法。
注:C#中一般称为“方法”),但这些函数不是执行程序本身的一部分,而是根据进程的需要按需载入,此时才能发挥作用。
DLL只有在应用程序需要时才被系统加载到进程的虚拟空间中,成为调用进程的一部分,此时该DLL也只能被该进程的线程访问,它的句柄可以被调用进程所使用,而调用进程的句柄也可以被该DLL所使用。
在内存中,一个DLL只有一个实例,且它的编制与具体的编程语言和编译器都没有关系,所以可以通过DLL来实现混合语言编程。
DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。
下面列出了当程序使用DLL 时提供的一些优点:[1]1) 使用较少的资源当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量。
这不仅可以大大影响在前台运行的程序,而且可以大大影响其他在Windows 操作系统上运行的程序。
2) 推广模块式体系结构DLL 有助于促进模块式程序的开发。
这可以帮助您开发要求提供多个语言版本的大型程序或要求具有模块式体系结构的程序。
模块式程序的一个示例是具有多个可以在运行时动态加载的模块的计帐程序。
3) 简化部署和安装当DLL 中的函数需要更新或修复时,部署和安装DLL 不要求重新建立程序与该DLL 的链接。
此外,如果多个程序使用同一个DLL,那么多个程序都将从该更新或修复中获益。
MFC下DLL编程(图解)
MFC 下DLL 编程(图解)DLL (Dynamic Link Library ,动态链接库)是微软公司为Windows 和OS/2操作系统设计一种供应用程序在运行时调用的共享函数库。
DLL 是应用程序的一种扩展,也是软件共享和重用的传统方法。
DLL 除了可同时被多个应用程序共享外,还可以在不改变调用接口(从而不需修改使用它的应用程序)的情况下,改进和升级里面的库函数。
而且DLL 与编写它的语言无关,例如,用VC 生成的规则DLL ,可以被VB 、Delphi 等生成的应用程序使用。
DLL 可以用多种语言和工具编写,我们这里只介绍如何使用MFC 来编写和使用DLL 。
相关说明文档位于MSDN 帮助的“目录\开发工具和语言\Visual Studio\Visual C++\常见编程方法\DLL\”中。
8.1 基础本节先讨论DLL 与静态库的区别,然后列出几种适合放置DLL 的目录,最后介绍MFC DLL 的三种类型。
8.1.1 DLL 与静态链接库静态链接库Lib (Static Link Library ),是在编译的链接阶段将库函数嵌入到应用程序的内部。
如果系统中运行的多个应用程序都包含所用到的公共库函数,则必然造成很大的浪费。
这样即增加了链接器的负担,也增大了可执行程序的大小,还加大了内存的消耗。
Lib 的好处是应用程序可以独立运行,而不需要在操作系统中另外安装对应的DLL 。
而DLL 采用动态链接,对公用的库函数,系统只有一个拷贝(一般是位于系统目录的*.DLL 文件),而且只有在应用程序真正调用时,才加载到内存。
在内存中的库函数,也只有一个拷贝,可供所有运行的程序调用。
当再也没有程序需要调用它时,系统会自动将其卸载,并释放其所占用的内存空间。
参见图8-1。
图8-1 静态库函数与动态链接库的区别DLL 的缺点是应用程序不能独立运行,需要在操作系统中另外安装对应的DLL 。
例如,如果你的MFC 项目被设置成“在共享DLL 中使用MFC ”的,则虽然生成的可执行程序很使用静态库函数使用动态链接库小,但是在其他没有安装Visual C++(运行环境)的机器上是不能直接运行的,需要另外安装MFC的动态链接库(如mfc90.dll)。
mfc使用手册
mfc使用手册MFC(Microsoft Foundation Class Library)是微软提供的一个类库,用于简化Windows应用程序的开发过程。
以下是MFC使用手册的简要介绍:1. 简介:MFC是一个基于C++的类库,它提供了许多用于构建Windows应用程序的类和函数。
通过使用MFC,开发人员可以快速地构建具有一致外观和感觉的应用程序,并利用Windows平台提供的各种功能。
2. 安装和配置:在开始使用MFC之前,您需要安装Microsoft Visual Studio并确保安装了MFC开发工作负载。
安装完成后,您需要创建一个新的MFC项目或打开一个现有的MFC项目。
3. 创建MFC应用程序:要创建一个新的MFC应用程序,您需要使用Microsoft Visual Studio的向导。
选择“File”菜单中的“New”选项,然后选择“Project”。
在弹出的对话框中,选择“MFC Application”并按照向导的提示完成应用程序的创建过程。
4. MFC类库:MFC提供了许多用于构建应用程序的类和函数。
以下是一些常用的MFC类:CWinApp:应用程序对象类,用于管理应用程序级别的操作,例如初始化应用程序和退出应用程序。
CWnd:窗口类,用于管理窗口的各种操作,例如创建窗口、处理消息和绘制窗口。
CDocument:文档类,用于管理应用程序中的文档数据。
CView:视图类,用于管理应用程序中的视图,例如显示文档数据和与用户交互。
5. MFC消息处理:MFC使用消息传递机制来处理用户与应用程序的交互。
每个窗口和控件都处理一组预定义的消息,例如鼠标点击、键盘输入和窗口大小改变等。
通过覆盖类中的虚函数,您可以定义应用程序如何响应这些消息。
6. MFC对话框和控件:MFC提供了许多内置的对话框和控件,例如按钮、文本框和列表框等。
您可以使用对话框编辑器来创建对话框,并将控件拖放到对话框中。
MFC调用IDL
经过一晚上的努力终于解决了在VS2008下VC++ 调用IDL的所有的问题。
环境:VS2008下的VC++ENVI4.7下的IDL7.1第一步:打开一个MFC的MFC的应用程序,并添加一个按钮,工程名为:hello1第二步:设置VS2008如:项目->hello1属性->配置属性->链接器->输入在对话框的附加依赖项:填写idl.lib第三步:在C:\Program Files (x86)\ITT\IDL71\external\include找到idl_export.h,把他放在hello1的工程文件里面,和其他.h文件放在一块第四步:在MFC的Button1的单击事件中,写入代码如下:HANDLE hInstance=AfxGetInstanceHandle();IDL_Win32Init(0,hInstance,NULL,0);IDL_ExecuteStr(".compile 'C:\Users\acer\Desktop\d_map.pro'");IDL_ExecuteStr("d_map");IDL_Cleanup(TRUE);注意:d_map.pro 文件放在C:\Users\acer\Desktop如果是想编译XX.sav文件,格式如:IDL_ExecuteStr(".restore, 'C:\Users\acer\Desktop\XX.sav'");其他代码不变还用一个注意事项是:添加idl_export.h头文件如:运行截图:不过在开始碰到很多系统问题如:我的系统是win7系统,开始新建MFC总是报错:mfc90ud.dll丢失,最后解决了是路径问题,解决方法是:“工具”—>“选项”—>“项目和解决方案”—>“VC++目录”,在可执行文件栏中加入下面的路径:$(SystemRoot)\System32$(SystemRoot)$(SystemRoot)\System32\wbem。
MFC调用DLL操作数据库并显示结果集
功能说明:可打开一个数据库,获取其中任何一个表格的内容,DLL生成的工程和调用的工程在同一工作空间,DLL库中的函数调用声明是__stdcall方式,用.def文件导出函数。
一、用MFC中的CListCtrl控件创建一个列表1、创建一个MFC工程新建(New)——工程(Project)——MFC AppWizard(exe)——填好工程名(Project Name)——确定(OK)——选择基本对话框(Dialog)——完成(Finish)2、添加列表控件(CListCtrl)在工作区打开ResourceView界面在Dialog文件夹中找到建立的窗口,在控件工具栏里面选择列表控件拖入到窗口中,用鼠标拖拽的方式设定合适的大小(如果没有控件工具栏,右击窗口工具栏,在弹出的列表中点击选中控件即可)。
3、关联对象变量点击选中新添加的列表控件,点击菜单栏中的查看,选中建立类向导,在弹出的窗口中选择Member Variables选项卡,在Contrls IDs:列中招列表控件对应的ID(查看ID 可右击列表控件,选择属性即可)并双击(或者点击选中后再点击窗口左边的Add Variable 按钮),在弹出的窗口中设置对象的名字及类型。
4、设置列表控件的风格在OnInitDialog()中添加下面的代码:LONG lStyle;lStyle = GetWindowLong(m_List.m_hWnd, GWL_STYLE); //获取当前窗口stylelStyle &= ~LVS_TYPEMASK; //清除显示方式位lStyle |= LVS_REPORT; //设置styleSetWindowLong(m_List.m_hWnd, GWL_STYLE, lStyle); //设置styleDWORD dwStyle = m_List.GetExtendedStyle();dwStyle |= LVS_EX_FULLROWSELECT; //选中某行使整行高亮(只适用与report 风格的listctrl)dwStyle |= LVS_EX_GRIDLINES; //网格线(只适用与report风格的listctrl) dwStyle |= LVS_EX_CHECKBOXES; //item前生成checkbox控件m_List.SetExtendedStyle(dwStyle); //设置扩展风格二、创建生成DLL文件的工程1、添加一个新的工程到当前工作空间中工程——增加到工程——新建——工程选项卡——Win32 Console Application ——填好工程名——选择添加到当前工作空间——确定2、在DLL工程中添加.cpp文件,首先导入ADO动态链接库msado15.dll代码如下:#import "c:Program Files\Common Files\System\ado\msado15.dll"no_namespace rename("EOF","adoEOF")定义三个主要的操作对象:_ConnectionPtr m_pConnect; //定义链接对象_RecordsetPtr m_pRecord; //定义记录集对象_CommandPtr m_pCommand; //定义命令对象编辑相关的函数,初始化COM和链接数据库函数、获取记录集函数等,如://初始化COM库和链接数据库_ConnectionPtr& __stdcall OnInitADOConn(_bstr_t strConnect){::CoInitialize(NULL);try{//对象实例化m_pConnect.CreateInstance(__uuidof(Connection));m_pConnect->Open(strConnect,"","",adModeUnknown); //建立链接//MessageBox(NULL,"链接成功!","提示",0);}catch(_com_error e){MessageBox(NULL,e.Description(),"error",0);}return m_pConnect;}//获取记录集_RecordsetPtr& __stdcall GetRecordSet(_bstr_t bstrSQL,_bstr_t strConnect){try{// 连接数据库,如果Connection对象为空,则重新连接数据库if(m_pConnect == NULL)OnInitADOConn(strConnect);//对象实例化m_pRecord.CreateInstance(__uuidof(Recordset));m_pRecord->Open(bstrSQL,m_pConnect.GetInterfacePtr(),adOpenDynamic,ad LockOptimistic,adCmdText);//MessageBox(NULL,"成功获取记录集!","提示",0);}catch(_com_error e){MessageBox(NULL,e.Description(),"error",0);}return m_pRecord;}//执行命令对象_RecordsetPtr& __stdcall ExeCommand(_bstr_t bstrSQL,_bstr_t strConnect){try{// 连接数据库,如果Connection对象为空,则重新连接数据库if(m_pConnect == NULL)OnInitADOConn(strConnect);m_pCommand.CreateInstance(__uuidof(Command));m_pCommand->put_ActiveConnection((_variant_t)((IDispatch*)m_pConnect));m_pCommand->CommandText = bstrSQL;m_pRecord = m_pCommand->Execute(NULL,NULL,adCmdText);//MessageBox(NULL,"成功执行命令对象!","提示",0);}catch(_com_error e){MessageBox(NULL,e.Description(),"error",0);}return m_pRecord;}//执行SQL语句BOOL __stdcall ExecuteSQL(_bstr_t bstrSQL,_bstr_t strConnect) {try{// 是否已经连接数据库if(m_pConnect == NULL)OnInitADOConn(strConnect);m_pConnect->Execute(bstrSQL,NULL,adCmdText);//MessageBox(NULL,"执行SQL语句成功!","提示",0);return true;}catch(_com_error e){MessageBox(NULL,e.Description(),"error",0);return false;}}//断开链接void __stdcall ExitConnect(){try{if(m_pRecord != NULL){m_pRecord->Close();m_pRecord = NULL;}if(m_pConnect != NULL){m_pConnect->Close();m_pConnect = NULL;}if(m_pCommand != NULL){m_pCommand = NULL;}//MessageBox(NULL,"成功断开链接!","提示",0);}catch(_com_error e){MessageBox(NULL,e.Description(),"error",0);return;}::CoUninitialize();}3、.def文件导出函数LIBRARY SqlDllNo_ClassEXPORT SOnInitADOConn //函数名GetRecordSet //函数名ExeCommand //函数名ExecuteSQL //函数名ExitConnect //函数名注释:当同一工作空间中有两个工程时,要编译哪个工程时可在组建工具栏中选择(组建工具栏可右击工具栏空白处在组建前面打钩,即可显示组建工具栏);如下图:三、调用DLL操作数据库1、在myDataListDlg.cpp前面定义全局变量,在myDataListDlg.h中添加#import "c:Program Files\Common Files\System\ado\msado15.dll" no_namespace rename("EOF","adoEOF")导入ADO动态链接库#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif在上面这段代码的后面添加下面的代码HINSTANCE hDLL = NULL; //定义动态链接库句柄//给几个dll中的函数的指针取别名typedef void (__stdcall * lpConn)(_bstr_t strConnect);typedef _RecordsetPtr& (__stdcall* lpRec)(_bstr_t bstrSQL,_bstr_t strConnect); //__stdcall绝对不能少,否则会出错typedef _RecordsetPtr& (__stdcall* lpCmd)(_bstr_t bstrSQL,_bstr_t strConnect);typedef BOOL (__stdcall* lpExe)(_bstr_t bstrSQL,_bstr_t strConnect);typedef void (__stdcall* lpExit)();//定义几个dll中的函数指针lpConn OnInitADOConn = NULL;lpRec GetRecordSet = NULL;lpExe ExecuteSQL = NULL;lpExit ExitConnect = NULL;2、加载DLL,获取函数地址在OnInitDialog()函数中的// TODO: Add extra initialization here后面添加下列代码_RecordsetPtr m_pRecord;//_bstr_t strSQL = "insert into SuperCar values('Aston Martin',4.5,370,270)"; _bstr_t strSQL = "delete from SuperCar where CarName='Aston Martin'"; _bstr_t strConnect = "Driver={SQLServer};Server=10.0.0.44;Database=Car;UID=sa;PWD=111111";hDLL = LoadLibrary("SqlDllNo_Class.dll");if(hDLL != NULL){MessageBox("加载SqlDllNo_Class.dll成功");OnInitADOConn = (lpConn)GetProcAddress(hDLL,"OnInitADOConn"); if(OnInitADOConn != NULL){// 初始化COM库并连接数据库OnInitADOConn(strConnect);}ExecuteSQL = (lpExe)GetProcAddress(hDLL,"ExecuteSQL");if(ExecuteSQL != NULL){ExecuteSQL(strSQL,strConnect);}GetRecordSet = (lpRec)GetProcAddress(hDLL,"GetRecordSet");if(GetRecordSet != NULL){//获取记录集_bstr_t strTempSQL = "select * from SuperCar";m_pRecord = GetRecordSet(strTempSQL,strConnect);}ExitConnect = (lpExit)GetProcAddress(hDLL,"ExitConnect");}3、获取数据库表格中的数据,添加到创建的列表中FieldsPtr fields; //定义一个列集对象FieldPtr field; //定义一个列对象m_pRecord->get_Fields (&fields); //将获取的记录集中的列集放到列集对象fields中long nColCount; //定义记录集中列数fields->get_Count(&nColCount); //将列集中的列的个数放到nColCount 中。
C#下开发及调用dll文件的方法
C#下开发及调用dll文件的方法在.net中,可调用的dll(动态链接库)文件其实就是一个类库。
我们可以通过写一个类,然后把它编译成dll文件形式,在其他的项目中就可以直接调用此编译好的dll文件,而不用重复写这个类的代码。
下面详细介绍此过程:一、开发dll文件(1)打开vs2005,新建项目中模板选择“类库”(2)在解决资源管理器里面添加一文件夹“First”,在其中添加两个类MathAdd和MathMinus,在其父目录里直接添加一个名为yun(写这个类的时候,我已经晕了,不知道取什么名字好,于是就yun了)的类。
下面是各个类的代码,注意类前一定要加上public,不然这个类会被当做是私有的,不能够被引用,当初我就是犯了这个错误,弄个了好久才想起,真是追悔莫及啊。
类中的方法为静态或非静态都可以。
MathAdd类代码using System;using System.Collections.Generic;using System.Text;namespace noo.First{public class MathAdd{public int add( int a,int b){return a + b;}public static int Muti(int a, int b){int mutiSum;mutiSum = a * b;return mutiSum;}}}MathMinus类代码using System;using System.Collections.Generic;using System.Text;namespace noo.First{public class MathMinus{public static int minus(int a, int b){return a - b;}}}yun类代码using System;using System.Collections.Generic;using System.Text;namespace noo{public class yun{public int add(int a, int b,int c){return a + b-c;}}到此,dll代码其实已经写好,这里我们可以发现,其实dll文件就是一个一个封装好的类库而已。
(1)MFC调用DLL基本步骤
MFC调用DLL基本步骤
2013-5-9
第一步:创建动态链接库
1、创建动态链接库工程
2、选择一个可以到处某些符号的DLL工程
3、添加Add加法函数。
打开Math.cpp文件,在文件最后输入函数代码
打开Math.h文件,在文件中加入函数声明语句,以方便外部调用Add函数
4、按F7或者Build按钮,此时将产生Math.dll和Math.lib文件,在Debug文件夹内,Math.h文件在Debug文件外
第二步在工程中使用DLL
1、在2DCAD中添加调用DLL的对话框并进行设置ID号
2、添加对话框类CTestDllDlg,并添加成员变量
3、将动态链接库文件复制到2DCAD目录下,有三个Math.dll、Math.lib、Math.h
4、给等号按钮添加消息处理
打开CTestDllDlg的OnButtonEqual函数,调用函数实现求和。
修改函数代码如下:
在TestDllDlg.cpp中包含动态链接库Math.dll的头文件Math.h:#include “Math.h”
5、将Math.lib加入到工程链接库
6、在2DCAD程序中弹出CTestDllDlg对话框
为2DCAD添加一个顶层菜单DLL和一个菜单项使用[Math.dll],修改菜单项ID为ID_DLL_MATH,并添加消息处理函数
修改函数如下:
在MainFrm.cpp中包含对话框类头文件:#include “TestDllDlg.h”
6、编译并运行2DCAD程序即可。
dllmain调用逻辑
dllmain调用逻辑DLL(动态链接库)的`DllMain` 函数是一个特殊的入口点,它在以下几个时刻被Windows系统调用:1. 当DLL被加载时:当一个应用程序加载一个DLL时,`DllMain` 函数会被自动调用。
这通常发生在以下几种情况:* 当应用程序启动时,如果它需要加载DLL。
* 当应用程序通过`LoadLibrary` 函数显式加载DLL时。
2. 当DLL被卸载时:当一个DLL被卸载时,`DllMain` 函数也会被自动调用。
这通常发生在以下几种情况:* 当应用程序关闭时,如果它之前加载了该DLL。
* 当应用程序通过`FreeLibrary` 函数显式卸载DLL时。
3. 在DLL中的线程创建时:每当在DLL中创建一个新的线程,`DllMain` 函数也会被调用,但仅当`DLL_THREAD_ATTACH` 被设置时。
这意味着如果你想在一个新线程开始执行时执行某些操作,你应该在`DllMain` 函数中检查这个标志,并在需要的时候进行设置。
4. 在DLL中的线程退出时:当在DLL中的线程结束时,`DllMain` 函数会被调用,但仅当`DLL_THREAD_DETACH` 被设置时。
这意味着如果你想在某个线程结束时执行某些清理操作,你应该在`DllMain` 函数中检查这个标志,并在需要的时候进行设置。
需要注意的是,`DllMain` 函数应当小心处理这些事件,因为不正确的处理可能会导致不稳定的行为或资源泄漏。
例如,如果你在`DllMain` 函数中启动新的线程,但没有正确地处理`DLL_THREAD_ATTACH` 和`DLL_THREAD_DETACH`,你可能会在应用程序关闭时留下未完成的线程。
mfc调用dll报无法解析的外部符号
题目:MFC调用DLL报无法解析的外部符号近年来,随着Windows操作系统的广泛应用,MFC(Microsoft Foundation Class)作为Windows开发的重要工具之一,广泛应用于软件开发领域。
而调用动态信息库(Dynamic Link Library,简称DLL)则是在MFC开发过程中常见的操作。
但是在实际开发中,经常会遇到MFC调用DLL时报“无法解析的外部符号”的问题,给开发者带来了不少困扰。
本文将从以下几个方面探讨MFC调用DLL报无法解析的外部符号的原因及解决方法。
一、了解外部符号的概念外部符号是指在C/C++语言中通过函数或变量名表达的标识符。
在编写程序时,当我们使用其他模块或库中定义的函数或变量时,就需要使用外部符号来声明或引用这些函数或变量。
二、分析出现“无法解析的外部符号”的原因1. 头文件未正确包含当在MFC项目中调用DLL的函数或变量时,首先要确保在MFC项目中正确包含了相关头文件。
有时,因为头文件路径设置不正确,或者头文件名称与DLL中的定义不一致,导致无法解析外部符号的错误。
2. 函数或变量未导出在创建DLL时,需要明确指定哪些函数或变量是可以被外部调用的,这就需要使用`__declspec(dllexport)`来声明导出函数或变量。
如果在DLL中未正确导出需要调用的函数或变量,就会出现无法解析外部符号的错误。
3. 使用C++编译器与信息器在MFC项目中调用DLL时,要确保使用相同的C++编译器与信息器。
有时,因为使用了不同版本或不兼容的编译器与信息器,导致在信息过程中无法解析外部符号。
4. 函数或变量名称冲突在MFC项目和DLL中,如果存在相同名称的函数或变量,就会出现名称冲突的问题,导致无法解析外部符号。
三、解决“无法解析的外部符号”的方法1. 检查头文件路径与名称确保在MFC项目中正确包含了DLL的头文件,并且头文件路径和文件名与DLL中的定义一致。
MFC中引用DLL
MFC中引用DLLDLL的背景知识静态链接和动态链接 当前链接的目标代码(.obj)如果引用了一个函数却没有定义它,链接程序可能通过两种途径来解决这种从外部对该函数的引用:静态链接 链接程序搜索一个或者多个库文件(标准库.lib),直到在某个库中找到了含有所引用函数的对象模块,然后链接程序把这个对象模块拷贝到结果可执行文件(.exe)中。
链接程序维护对该函数的所有引用,使它们指向该程序中现在含有该函数拷贝的地方。
动态链接 链接程序也是搜索一个或者多个库文件(输入库.lib),当在某个库中找到了所引用函数的输入记录时,便把输入记录拷贝到结果可执行文件中,产生一次对该函数的动态链接。
这里,输入记录不包含函数的代码或者数据,而是指定一个包含该函数代码以及该函数的顺序号或函数名的动态链接库。
当程序运行时,Windows装入程序,并寻找文件中出现的任意动态链接。
对于每个动态链接,Windows装入指定的DLL并且把它映射到调用进程的虚拟地址空间(如果没有映射的话)。
因此,调用和目标函数之间的实际链接不是在链接应用程序时一次完成的(静态),相反,是运行该程序时由Windows完成的(动态)。
这种动态链接称为加载时动态链接。
还有一种动态链接方式下面会谈到。
动态链接的方法 链接动态链接库里的函数的方法如下:加载时动态链接(Load_time dynamic linking) 如上所述。
Windows搜索要装入的DLL时,按以下顺序:应用程序所在目录→当前目录→Windows SYSTEM目录→Windows目录→PATH环境变量指定的路径。
运行时动态链接(Run_time dynamic linking) 程序员使用LoadLibrary把DLL装入内存并且映射DLL到调用进程的虚拟地址空间(如果已经作了映射,则增加DLL的引用计数)。
首先,LoadLibrary搜索DLL,搜索顺序如同加载时动态链接一样。
然后,使用GetProcessAddress 得到DLL中输出函数的地址,并调用它。
dll的动态调用与静态调用
C++动态与静态调用dll一).静态调用其步骤如下:1.把你的youApp.DLL拷到你目标工程(需调用youApp.DLL的工程)的Debug目录下;2.把你的youApp.lib拷到你目标工程(需调用youApp.DLL的工程)目录下;3.把你的youApp.h(包含输出函数的定义)拷到你目标工程(需调用youApp.DLL的工程)目录下;4.打开你的目标工程选中工程,选择Visual C++的Project主菜单的Settings菜单;5.执行第4步后,VC将会弹出一个对话框,在对话框的多页显示控件中选择Link页。
然后在Object/library modules输入框中输入:youApp.lib6.选择你的目标工程Head Files加入:youApp.h文件;7.最后在你目标工程(*.cpp,需要调用DLL中的函数)中包含你的:#include "youApp.h"注:youApp是你DLL的工程名。
2.动态调用其程序如下:动态调用时只需做静态调用步骤1.{HINSTANCE hDllInst = LoadLibrary("youApp.DLL");if(hDllInst){typedef DWORD (WINAPI *MYFUNC)(DWORD,DWORD);MYFUNC youFuntionNameAlias = NULL; // youFuntionNameAlias 函数别名youFuntionNameAlias = (MYFUNC)GetProcAddress (hDllInst,"youFuntionName");// youFuntionName 在DLL中声明的函数名if(youFuntionNameAlias){youFuntionNameAlias(param1,param2);}FreeLibrary(hDllInst);}}采用动态库技术对于升级软件版本更加容易。
mfc使用教程
mfc使用教程MFC使用教程不要标题MFC是Microsoft Foundation Class的缩写,是一套C++的库,用于开发Windows平台的应用程序。
以下是一个简单的MFC使用教程,帮助你了解如何创建一个基本的MFC应用程序。
首先,打开Visual Studio并选择创建新项目。
在项目模板中,选择"MFC应用程序"。
在下一步中,选择"对话框"作为应用程序类型。
接下来,选择项目的名称和位置,然后点击"完成"按钮。
Visual Studio将自动生成一个MFC应用程序的基本框架。
应用程序的主要代码位于"MainFrm.cpp"和"MainFrm.h"文件中。
打开"MainFrm.cpp"文件,你将看到一个名为"Create"的函数。
在这个函数中,可以创建应用程序的主窗口。
在"Create"函数的内部,使用"MFC应用程序向导"提供的函数来创建一个对话框。
例如,可以使用"CDialogEx"类来创建一个简单的对话框。
在"Create"函数的最后,需要调用"ShowWindow"函数显示主窗口,并调用"UpdateWindow"函数来更新窗口。
在"MainFrm.h"文件中,你可以定义应用程序的主窗口类。
例如,可以继承自"CFrameWnd"类,并添加自定义的成员变量和函数。
在"MainFrm.cpp"文件的"Create"函数中,还可以添加一些自定义的代码,例如设置窗口的标题和大小,添加菜单和工具栏等。
最后,编译并运行应用程序。
你应该能够看到一个简单的MFC应用程序的窗口。
MFC控件使用详细教程
使用Windows标准控件我们在前面曾提到过,控件是一些行为标准化了的窗口,一般用于对话框或其它窗口中充当与用户交互的元素。
在Visual C++中,可以使用的控件分成三类:(1) Windows标准控件Windows标准控件由Windows操作系统提供,在Windows 95中还提供了一些新增的控件。
所有这些控件对象都是可编程的,我们可以使用Visual C++提供的对话框编辑器把它们添加到对话框中。
Microsoft基础类库(MFC)提供了封装这些控件的类,它们列于表6.1。
表6.1 Windows标准控件续表6.1前面提到过,在MFC中,类CWnd是所有窗口类的基类,很自然的,它也是所有控件类的基类。
Windows标准控件在以下环境下提供:•Windows 95•Windows NT 3.51及以后版本•Win32s 1.3•注意:•Visual C++ 4.2及以后版本不再支持Win32s。
(2) ActiveX控件ActiveX控件可用于对话框中,也可用于HTML文档中。
这种控件过去被称为OLE 控件。
本书将在专门的章节中来讲述关于ActiveX控件的知识。
这里仅指出ActiveX控件使用了与标准控件完全不同的接口和实现方法。
(3) 其它MFC控件类除了Windows标准控件和自己编写的或者来自于第三方软件开发商的ActiveX 控件以外,MFC还提供了另外三种控件,它们由下面的三个类进行封装:•类CBitmapButton用于创建以位图作为标签的按钮,位图按钮最多可以包括四个位图图片,分别代表按钮的四种不同状态。
•类CCheckListBox用于创建选择列表框,这种列表框中的每一项前面有一个复选框,以决定该项是否被选中。
•类CDragListBox用于创建一种特殊的列表框,这种列表框允许用户移动列表项。
在本章我们仅讲述第一类控件,即Windows标准控件。
所涉及的内容包括各个控件的使用及相应的技巧。
MFC下DLLlib的调用
MFC下DLL/lib的调用分类:C/C++ 2011-11-11 19:08 289人阅读评论(0) 收藏举报 1、简介:dll和.lib都是程序集合,便于代码重用。
都是二进制的文件。
.dll也叫动态链接库,与程序链接的方式为运行时链接(run-time linked),为PE (portable executable)格式,也就是程完整的程序。
.exe、.dll、.fon、.mod、.drv、.ocx 等等都是动态链接库。
如.exe为系统调用的函数集合。
.dll不存在同名引用,且有导出表,与导入表。
.lib也叫静态链接库,在编译时与程序链接(link-time linked),将“嵌入”到程序中。
会有冗余(程序文件代码的冗余和运行时内存存储的冗余),当两个lib相链接时地址会重新建立同。
在使用.lib之前,要在程序源代码中引用lib对应的头文件.h,这些头文件告诉编译器.lib 中有什么。
在生成.dll时,通常会生成一个.lib。
这个.lib将被编译到程序文件中,在程序运行的时候,告诉操作系统将要加载的.dll。
这个.lib包括对应.dll的文件名、顺序表(ordinal table包含.dll 暴露出的函数的进入点),在程序运行的时候,通过顺序表实现函数的跳转。
如果不想使用或者找不到该.lib,可以用LoadLibrary () Win32 API和GetLibrary () Win32 API。
VC IDE为了实现程序调试,会生成.PDB(程序数据库,二进制),里面包含源文件调用的文件信息和行信息。
这样就可以逐行调试了。
打开.lib,查看其ascii码,可以看到如@@My_Function1123的函数名,这些名称在编译时被编译器运用mangling mechanism进行了名称的mangling。
在程序的编译过程中,如果出现如下错误“unresolved symbol _some_funtion@1234”,通常是因为找不到引用过的外部函数对应的.lib文件,或者是.c、.cpp源文件。
MFC DLL的生成和调用实例
1.打开VS2012,依次选择文件—新建—项目—MFC DLL,在下方名称栏中输入工程命名OneDLL,在位置栏中选择存放工程文件的路径—确定—点击下一步—DLL类型:使用共享MFC DLL 的规则DLL—点击完成。
2. 其中我们感兴趣的是OneDLL.cpp文件和OneDLL. def文件。
OneDLL.cpp文件是DLL的主要的源代码文件,它包含了COneDLLApp类的定义;OneDLL.def文件包含了DLL提供的关于DLL在Wind ows下运行的一些信息,在这个文件中定义了一些参数,如DLL的名称和属性等,还声明了从DLL中输出的函数。
3.添加实现代码,黑色加粗部分为添加的代码。
#include "stdafx.h"#include "OneDLL.h"#ifdef _DEBUG#define new DEBUG_NEW#endifint Message(void);BEGIN_MESSAGE_MAP(COneDLLApp, CWinApp)END_MESSAGE_MAP()// COneDLLApp 构造COneDLLApp::COneDLLApp(){// TODO: 在此处添加构造代码,// 将所有重要的初始化放置在InitInstance 中}// 唯一的一个COneDLLApp 对象COneDLLApp theApp;// COneDLLApp 初始化BOOL COneDLLApp::InitInstance(){CWinApp::InitInstance();return TRUE;}int Message(void){MessageBox(NULL,_T("This is the example of testing DLL."),NULL,MB_OKCANCEL);return 1;}记得设为为多字节而非unicode编码。
怎么调用dll
HWND, HDC, HMENU ByVal variable As Long 结果为 Long 类型的表达式等Windows 句柄
INT, UINT ByVal variable As Long 结果为 Long 类型的表达式
LONG ByVal variable As Long 结果为 Long 类型的表达式
5、VB中进行32位动态库的声明时,函数名是大小写敏感的。在获得了需要的动态连接 库之后,就可以在VB中进行调用了。但是,由于VB不能验证应用程序传递到动态连接库中的参 数值是否正确,因此VB程序中大量的API调用可能会降低整个应用程序的稳定性,也会增加以 后维护的难度。所以,决定在VB程序中直接调用API函数时要慎重,但适当的使用API调用确实 能够有效地提高VB程序的性能。这之间的平衡需要编程人员根据实际情况来掌握。下面就具体介绍一下在VB中调用API函数时需要做的工作。
作为一种32位Windows应用程序的开发工具,VB5生 成的exe文件自然也都是32位的,通常情况下也只能调用32位的动态连接库。但是,并不是所有的32位动态库都能被VB生成的exe 文件正确地识别。一般来说,自己编写用于VB应用程序调用的动态连接库时,应注意以下几个方面的问题:
1、生成动态库时要使用__stdcall调用约定,而不能使用缺省的__cdecl调用约定;__stdcall 约定通常用于32位API函数的调用。
LPRECT variable As type 自定义类型的任意变量
LPSTR, LPCSTR ByVal variable As String 结果为 String 类型的表达式
LPVOID variable As Any 任何变量(在传递字符串的时候使用ByVal)
NET_如何生成DLL文件并且调用
NET_如何生成DLL文件并且调用生成DLL文件并调用的步骤如下:1. 创建一个新的项目:首先,在开发环境中创建一个新的项目,比如使用Visual Studio等IDE。
在新项目对话框中选择“Class Library”(类库)项目类型,并为项目指定一个名称,然后单击“确定”。
2.编写代码:在新创建的项目中,编写你的代码。
DLL文件通常包含了一些可复用的函数或类,可以被其他程序调用。
在DLL项目中,可以定义一些公共的类或方法,这些类或方法可以被其他应用程序引用并调用。
在DLL项目中,你可以编写你需要实现的功能代码。
3. 构建DLL文件:完成代码编写后,可以通过点击构建按钮(一般为“生成”或“Build”),来编译项目并生成DLL文件。
编译成功后,Visual Studio将生成一个.dll文件。
这个.dll文件包含了你在DLL项目中定义的类和方法的二进制代码。
4. 调用DLL文件:构建成功后,你可以使用生成的DLL文件。
首先,在你需要调用DLL函数的项目中,需要添加对DLL的引用。
右键点击项目并选择“添加引用”选项。
在弹出的对话框中,选择“浏览”(Browse),然后选择生成的DLL文件。
5.使用DLL函数:在项目中添加了对DLL的引用后,就可以在代码中调用DLL文件中的函数了。
通过在代码中使用方法、类或函数的名称,即可调用DLL文件中定义的函数。
需要注意的是,调用时要将所使用的命名空间或类名前缀添加到调用的函数或类名之前。
6.运行程序:完成调用DLL函数的代码编写后,你可以运行项目以测试DLL文件的功能。
通过构建并运行项目,你可以验证DLL文件是否按预期进行工作。
注意,当你运行项目时,应确保DLL文件已被正确地部署到项目的输出目录中。
总结:生成DLL文件并调用可以通过以下步骤实现:创建一个新的项目、编写代码、构建DLL文件、调用DLL文件、使用DLL函数和运行程序。
这些步骤可帮助你实现将代码封装为可复用的DLL文件,并在其他项目中调用。
VC.NET中定义和使用MFCDLL基础教程基础实例
中定义和使用MFCDLL基础教程基础实例VC++.NET中定义和使用MFC DLL什么是DLL?DLL指的是动态链接库(Dynamic Link Library),它是一个可以被多个应用程序(甚至是不同语言编写的应用程序)同时调用的可执行二进制文件,是一个可共享的库。
DLL是建立在客户/服务器通信的概念上,包含若干函数、类或资源的库文件,函数和数据被存储在一个DLL(服务器)上并由一个或多个客户导出而使用,这些客户可以是应用程序或者是其它的DLL。
在下面我们将通过一个具体的例子来说明如何利用定义一个DLL文件,并且在的应用程序中调用,这个例子的主要功能是通过DLL获取系统的机器名、操作系统类型和IP地址。
在中定义DLL文件选择菜单项,选择文件->新建->项目,在弹出的新建项目的对话框中,选择项目类型为Visual C++ 项目,类别为MFC的工程,在右边的模板中,选择MFC DLL模板,给项目取名为T estDLL,选择好项目的位置,按确定健,进入应用程序设置。
在应用程序设置中,我们可以看到,有三种DLL类型,它们依次对应着三类DLL。
静态DLL与共享DLL的区别是:前者使用的是MFC的静态链接库,生成的DLL文件长度大,一般不使用这种方式,后者使用MFC的动态链接库,生成的DLL文件长度小;动态链接到MFC的共享DLL 所有输出的函数应该以如下语句开始(用于正确切换MFC模块状态):AFX_MANAGE_STATE(AfxGetStaticModuleState( )) 扩展DLL用来建立MFC的派生类,只被用MFC类库所编写的应用程序调用。
常规DLL(包括静态与动态)的一个特点是在源文件里有一个继承CWinApp的类(从CWinApp派生,但没有消息循环),被导出的函数是C++类或者C++成员函数,调用常规DLL的应用程序不必一定是MFC应用程序。
扩展DLL和常规DLL不一样,它没有一个从CWinApp继承而来的类的对象,编译器默认了一个DLL入口函数DLLMain()作为对DLL的初始化。
MFC一些调用的步骤
MFC 一些调用的步骤 1,第一步,全局对象"theApp"的构造函数;2,真正的 main 函数隐藏在框架内,IDE 下 按 F11 可以进入 Main 函数3,跳转到 AfxWinMain 函数,看到调用了"InitInstace"虚函数,另外 CWinAPP 原来是从 CWinThread 派生的,是一个线程,以前没注意4,最后进入了 CWinThread::Run 函数,也就是进入了消息泵AfxMessageBox 引起死机 1,在 CListCtrl 右键菜单的执行中; 2,AfxMessageBox 的数据量 4K 左右; 结论: 不要用 AfxMessageBox 显示大量的数据设置树的节点高度Window 控件里面,树的节点高度是可以设置的,如下:tvis.hParent = hItem; tvis.itemex.mask = TVIF_TEXT|TVIF_INTEGRAL; tvis.itemex.pszText = TEXT("3 倍高度节点"); tvis.itemex.iIntegral = 3; m_wndTree.InsertItem(&tvis);iIntegral 表示是普通节点的 3 倍高度.一个小技巧,发现网上提及较少,故这里列出.VC++ 6.0 的小花招 Visual Studio 系列中产品中,Visual Studio 6.0 是最经典的一个版本,虽 然后来有 Visual Studio .NET 2003,以及 2005,也确实添加了很多让我觉得 激动的特性,但是从使用细节的细腻程度上来看,VS 6.0 无疑是最棒的.我 们一些同事甚至试图把 2005 的 C++编译器独立的拿到 Visual Studio 6.0 中 来用,也不愿意升级到.NET 上来用,可见其魅力.和 VS 6.0 这个产品的成熟相比,VC++ 6.0 的编译器的的确确相对来说有些糟 糕,其中最被诟病的是对模板技术支持很不好.下面我想做的一件事情,就是 向那些继续留恋 VC++ 6.0 的朋友,介绍一些小花招,来避开 VC++ 6.0 的一些 编译器缺陷.的作用域问题. 1)for (type var=expression;;) 中变量 var 的作用域问题.按照 C++标准,这里定义的变量 var 出了 for 循环应该被销毁.也就是说下面 这段代码是有效的:for (int i = 0; i < 100; ++i) func(); for (int i = 0; i < 100; ++i) func2();而下面这段代码应该编译不过:for (int i = 0; i < 100; ++i) { if (has_found_it()) { handle_find_result(); break; } } if (i == 100) do_not_found();然而 VC++ 6.0 对于第一段代码会报变量 i 重复定义错误,而第二段代码编译 通过.为了让 VC++ 6.0 的 for 语句看起来符合 C++标准,你可以这样做:#define for if (0); else for你会发现很有趣,这样 define 一下后,VC++ 6.0 的 for 语句完全符合 C++标 准了!而且由于编译器的优化,Release 版本不会增加任何额外的开销.喜欢"钻牛角尖"的朋友可能会说:嗯,不错的主意.但是——为什么不这样 做:#define for if (1) for嗯?看起来也可以.还是让我们看一个用例:if (cond) for (int i = 0; i < 100; ++i) func1(); else func2();进行宏代码展开后,成为:if (cond) if (1) for (int i = 0; i < 100; ++i) func1(); else func2();这个结果显然不能符合我们的原意.这里 func2();语句永远得不到执行机会.2)模板参数类型如果不出现在参数列表中,则不能作为返回值类型. 模板参数类型如果不出现在参数列表中,则不能作为返回值类型.由于编译器的缺陷,VC++ 6.0 不支持以下这种用法:template <class T1, class T2> T1 func(T2 arg) { T1 var; ... // 处理 var 过程 return var; }void test() { int result1 = func<int>(1); double result2 = func<double>(2); };很抱歉,这种用法 VC++ 6.0 不支持.让人恼火的是,VC++ 6.0 编译时不会提 示错误,但是生成的执行代码却很成问题.究其原因,是因为 VC++ 6.0 的 template 技术是在编译器的较高层次做的,真 正的编译器核心并不考虑模板.以上面的代码为例,对编译器核心来说,只是 有两个重载函数而已:int func(int arg); double func(int arg);如果是普通情况,只是返回值不同的函数,是不能同时存在的,编译器应该认 为这是一个错误. 但是很在模板情况下, 这两个函数被简单认为是同一个函数. 因为 VC++ 6.0 会为每个函数根据它的:1)所在的 namespace; 2)所在的类的类名(如果是成员函数); 3)函数名; 4)函数调用方式(cdecl,stdcall 还是 fastcall); 5)所有参数的类型; 而生成一个唯一标识该函数的函数名.这个过程叫 Name Mangling,是所有 C ++编译器都要进行的工作.而另一个背景是,很多 C++编译器生成的目标文件 (.obj 文件)有一些和模板相关的特殊信息,包括也标识了某个函数是否模 板函数.这是因为一个模板函数在多个源文件(.cpp 文件)中被调用的话, 这个模板函数就会在这些源文件编译生成的目标文件(.obj 文件)中都定义 (definition)一份.为了支持模板,link 程序显然必须知道这个函数是模 板函数,从而随意选择一个定义(丢弃其余的定义),而不是报符号重复定义 错误.因为函数名,参数列表等完全一致,所以这两个函数 Name Mangling 后生成的 名字是一样的,并且,它们都被标识为这是模板函数.从而,link 程序在工 作的时候,简单地将其中一个函数定义给抛弃了.那么,如果我们非要提供上述的 func 函数,怎么办?我们来点花招:template <class T1> class func { private: T1 var;public: template <class T2> func(T2 arg) {... // 处理 var 过程 } operator T1() const { return var; } };我们再来使用 func 这个"函数":void test() { int result1 = func<int>(1); double result2 = func<double>(2); };呵呵,你会发现,它还真象是你期望的正常工作.3)仿真 VC++提供的关键字__uuidof. VC++提供的关键字__uuidof. 提供的关键字__uuidof这个技巧不是针对 VC++ 6.0 缺陷的,而是针对 VC++扩展语法的.这个技巧的 来由,是为了某些希望有一天有可能要脱离 Visual C++环境进行开发的人员. 为了脱离 VC++,你需要谨慎使用它的所有扩展语法.例如本文讨论的__uuido f.我们先来看看一个例子:class __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BA")) Clas s;struct __declspec(uuid("B372C9F6-1959-4650-960D-73F20CD479BB")) Int erface;void test() { CLSID clsid = __uuidof(Class); IID iid = __uuidof(Interface); ... }这比起你以前定义 uuid 的方法简单多了吧?可惜,这样好用的东西,它只在 VC++中提供.不过没有关系,我们这里介绍一个技巧,可以让你在几乎所有 C ++编译器中都可以这样方便的使用__uuidof.这里没有说是所有,是因为我们 使用了模板特化技术,可能存在一些比较"古老"的 C++编译器,不支持该特 性.也许你已经迫不及待了.好,让我们来看看:#include <string> #include <cassert>inline STDMETHODIMP_(GUID) GUIDFromString(LPOLESTR lpsz) { HRESULT hr; GUID guid; if (lpsz[0] == '{') { hr = CLSIDFromString(lpsz, &guid); }else{std::basic_string<OLECHAR> strGuid;strGuid.append(1, '{');strGuid.append(lpsz);strGuid.append(1, '}');hr = CLSIDFromString((LPOLESTR)strGuid.c_str(), &guid);}assert(hr == S_OK);return guid;}template <class Class>struct _UuidTraits {};#define _DEFINE_UUID(Class, uuid) \template<> \ struct _UuidTraits<Class>{ \static const GUID& Guid(){ \static GUID guid = GUIDFromString(L ## uuid); \return guid; \} \}#define __uuidof(Class) _UuidTraits<Class>::Guid()#define DEFINE_CLSID(Class, guid) \class Class; \_DEFINE_UUID(Class, guid)#define DEFINE_IID(Interface, iid) \struct Interface; \_DEFINE_UUID(Interface, iid)这样一来,就已经模拟出一个__uuidof关键字。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MFC调用DLL基本步骤
2013-5-9
第一步:创建动态链接库
1、创建动态链接库工程
2、选择一个可以到处某些符号的DLL工程
3、添加Add加法函数。
打开Math.cpp文件,在文件最后输入函数代码
打开Math.h文件,在文件中加入函数声明语句,以方便外部调用Add函数
4、按F7或者Build按钮,此时将产生Math.dll和Math.lib文件,在Debug文件夹内,Math.h文件在Debug文件外
第二步在工程中使用DLL
1、在2DCAD中添加调用DLL的对话框并进行设置ID号
2、添加对话框类CTestDllDlg,并添加成员变量
3、将动态链接库文件复制到2DCAD目录下,有三个Math.dll、Math.lib、Math.h
4、给等号按钮添加消息处理
打开CTestDllDlg的OnButtonEqual函数,调用函数实现求和。
修改函数代码如下:
在TestDllDlg.cpp中包含动态链接库Math.dll的头文件Math.h:#include “Math.h”
5、将Math.lib加入到工程链接库
6、在2DCAD程序中弹出CTestDllDlg对话框
为2DCAD添加一个顶层菜单DLL和一个菜单项使用[Math.dll],修改菜单项ID为ID_DLL_MATH,并添加消息处理函数
修改函数如下:
在MainFrm.cpp中包含对话框类头文件:#include “TestDllDlg.h”
6、编译并运行2DCAD程序即可。