动态链接库的制作与调用

来源:互联网 发布:c语言中cout什么意思 编辑:程序博客网 时间:2024/06/04 19:07
    
 题目:创建一个动态链接库,实现画一棵树。
1).启动Visual C++6.0或者C++ Builder 5.0
 .在WINDOWS98或WINDOWS 2000环境下,找到Visual C++6.0或者C++ Builder 5.0图标,双击之。为了不使Visual C++6.0或者C++ Builder 5.0的默认搜索路径与WINDOWS其他软件相冲突,清修改Visual C++6.0或者C++ Builder 5.0图标的属性。在属性|程序|批处理一栏中填上你自己的批处理程序名。以便启动时,首先运行你的批处理程序。然后在该批处理程序中,写上path=...路径。
2).设置用户程序子目录
    设置用户程序子目录的目的是,将所有编程时产生的中间文件和最终执行程序文件全部
放在自己的目录中,以便管理。
 3).创建和输入程序
   Visual C++6.0启动后,要先建立一个project工程文件。方法为:
   ·选择File|new 菜单项,将弹出New 对话框。
   ·单击Projects 选项卡
   ·在Location中填用户子目录路径
   ·在Project name中填入工程名(如MyDll)
   ·在列表中选择MFC AppWizard(dll),表示你编制的应用程序将生成动态链接库文件(.dll)
   ·按照提示创建一个自己想要的工程
 
²        定位到mydll.h文件处,添加动态链接库的函数原型声明,下面为mydll.h的内容:
 // MyDll.h : main header file for the MYDLL DLL
 
#include "resource.h"            // main symbols
 
/////////////////////////////////////////////////////////////////////////////
// CMyDllApp
// See MyDll.cpp for the implementation of this class
//
int DrawTree(CPaintDC *dc,int xStart,int yStart,double length,double angle,int num);
class CMyDllApp : public CWinApp
{
public:
       CMyDllApp();
 
// Overrides
       // ClassWizard generated virtual function overrides
       //{{AFX_VIRTUAL(CMyDllApp)
       public:
       virtual BOOL InitInstance();
       //}}AFX_VIRTUAL
 
       //{{AFX_MSG(CMyDllApp)
              // NOTE - the ClassWizard will add and remove member functions here.
              //    DO NOT EDIT what you see in these blocks of generated code !
       //}}AFX_MSG
       DECLARE_MESSAGE_MAP()
};
 
²        定位到mydll.cpp 文件处,添加动态链接库中的函数的实现部分,下面为mydll.cpp的内容:
      // MyDll.cpp : Defines the initialization routines for the DLL.
//
 
#include "stdafx.h"
#include "MyDll.h"
#include <math.h>
 
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// The one and only CMyDllApp object
 
CMyDllApp theApp;
int DrawTree(CPaintDC *dc,int xStart,int yStart,double length,double angle,
                      int num)
{
       int xEnd,yEnd;
       if (num==0) return 1;
       xEnd=xStart+(int)(length*cos(angle));
       yEnd=yStart+(int)(length*sin(angle));
       dc->MoveTo(xStart,yStart);
       dc->LineTo(xEnd,yEnd);
       DrawTree(dc,xEnd,yEnd,length*0.6,angle+0.624,num-1);
       DrawTree(dc,xEnd,yEnd,length*0.85,angle+0.08,num-1);
       DrawTree(dc,xEnd,yEnd,length*0.65,angle-0.6,num-1);
       return 1;
}
 
²        在mydll.def中引出DrawTree函数,下面为mydll.def的内容。
 ; MyDll.def : Declares the module parameters for the DLL.
 
LIBRARY      "MyDll"
DESCRIPTION 'MyDll Windows Dynamic Link Library'
 
EXPORTS
    ; Explicit exports can go here
       DrawTree
       DllCanUnloadNow PRIVATE
       DllGetClassObject PRIVATE
       DllRegisterServer PRIVATE
l         编译程序
 [思考问题]
²        程序中大小写用错了,结果会怎样?
²        如果返回类型void没有,结果会怎样,是否需要return语句?
²        编译中若有警告信息,影响程序运行吗?
²        如何编写动态链接库文件以及步骤?
 
动态链接库文件的调用
1、实验目的
(1)       解和掌握类和指向函数的指针的使用。
(2)       了解和掌握宏的使用。
(3)       掌握如何显示调用动态链接库文件。
(4)       掌握如何隐示调用动态链接库文件。
(5)       调用动态链接库文件的步骤。
2、实验要求
熟练掌握在自己的应用程序中调用动态连接库文件的方法
3、实验步骤与内容
1)        启动Visual C++6.0或者C++ Builder 5.0
 .在WINDOWS98或WINDOWS 2000环境下,找到Visual C++6.0或者C++ Builder 5.0图标,双击之。为了不使Visual C++6.0或者C++ Builder 5.0的默认搜索路径与WINDOWS其他软件相冲突,清修改Visual C++6.0或者C++ Builder 5.0图标的属性。在属性|程序|批处理一栏中填上你自己的批处理程序名。以便启动时,首先运行你的批处理程序。然后在该批处理程序中,写上path=...路径。
2)设置用户程序子目录
    设置用户程序子目录的目的是,将所有编程时产生的中间文件和最终执行程序文件全部
放在自己的目录中,以便管理。
    3)创建和输入程序
   Visual C++6.0启动后,要先建立一个project工程文件。方法为:
   ·选择File|new 菜单项,将弹出New 对话框。
   ·单击Projects 选项卡
   ·在Location中填用户子目录路径
   ·在Project name中填入工程名
   ·在列表中选择MFC AppWizard(exe),表示你编制的应用程序将生成可执行文件(.exe)
   ·按照提示创建一个自己想要的工程
    4)调用步骤
²        隐示链接
包含导出函数(或C++类)声明的头文件(.h)
导入库(.lib)文件
实际的DLL(.dll)文件
²        显示链接
          显示链接时,使用DLL的可执行程序在运行时通过函数调用来显示加载或卸载
          DLL,并通过函数指针来调用DLL的导出函数,要显示链接DLL,应用程序必须调用LoadLibrary来加载DLL,并获取模块句柄,调用GetProcAddress来获取应用程序要调用的导出函数的指针,使用完DLL后,应调用FreeLibrary来卸载DLL.
     5)主要程序代码
    (1)定位到TestDllView.h文件处,添加函数原型声明,下面为TestDllView.h的内容:
    // TestDllView.h : interface of the CTestDllView class
class CTestDllView : public CView
{
protected: // create from serialization only
                  CTestDllView();
                  DECLARE_DYNCREATE(CTestDllView)
 
// Attributes
public:
                  CTestDllDoc* GetDocument();
 
// Operations
public:
 
// Overrides
                  // ClassWizard generated virtual function overrides
                  //{{AFX_VIRTUAL(CTestDllView)
                  public:
                  virtual void OnDraw(CDC* pDC); // overridden to draw this view
                  virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
                  protected:
                  virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
                  virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
                  virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
                  //}}AFX_VIRTUAL
 
// Implementation
public:
                  virtual ~CTestDllView();
#ifdef _DEBUG
                  virtual void AssertValid() const;
                  virtual void Dump(CDumpContext& dc) const;
#endif
 
protected:
 
// Generated message map functions
protected:
                  //{{AFX_MSG(CTestDllView)
                  afx_msg void OnPaint();
                  //}}AFX_MSG
                  DECLARE_MESSAGE_MAP()
};
 
#ifndef _DEBUG // debug version in TestDllView.cpp
inline CTestDllDoc* CTestDllView::GetDocument()
   { return (CTestDllDoc*)m_pDocument; }
#endif
 
/////////////////////////////////////////////////////////////////////////////
 
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
 
#endif // !defined(AFX_TESTDLLVIEW_H__CFCBD8ED_D7AF_11D6_93F3_50784C6323E6__INCLUDED_)
(2)定位到视图类 CtestDllView的实现TestDllView.cpp中的函数OnPaint处,加入下列的代码:
     void CTestDllView::OnPaint()
{
       CPaintDC dc(this); // device context for painting
//     typedef int(*DRAWTREE)(CPaintDC *,int,int,double,double,
//            int);
              typedef int(*DRAWTREE)(CPaintDC *,int,int,double,double,int);
       DRAWTREE DrawTree;
       CRect rect;
       GetClientRect(rect);
       FARPROC lpfn=NULL;
       HINSTANCE hinst=NULL;
       hinst=LoadLibrary("MyDll.dll");
       if (hinst==NULL)
       {
              AfxMessageBox("不能加载动态链接库");
              return;
       }
       lpfn=GetProcAddress(hinst,"DrawTree");
       DrawTree=(DRAWTREE)lpfn;
       dc.SetMapMode(MM_LOENGLISH) ;
       if (lpfn==NULL)
              AfxMessageBox("不能加载画树函数");
       else
              DrawTree(&dc,rect.right/2,-rect.bottom *9/10,(double)rect.bottom *0.2,1.57,9);
       FreeLibrary(hinst);
       // TODO: Add your message handler code here
      
       // Do not call CView::OnPaint() for painting messages
}
6)运行界面
 
原创粉丝点击