动态连接库-隐式

 


DLL-正规的 DLL 共享MFC DLL
 导出函数、类

实例1: 
<注意:将此处两个函数封装到 Fun.h, Fun.cpp 中, 否则关联.exe调试时出错, 同实例3添加全局函数>
  MFC DLL 导出函数
1). 创建一个 MFC dll 程序( DLLExm2 ),  选择 Regular DLL using shared MFC DLL

2). 添加两个函数
 InsertOne:  不可以对外访问
 InsertSort: 可以对外访问

 void InsertOne(int _eArr[], int _nStCnt, int _e)
 {
  // 从这个有序序列的最后一个元素开始
  for(int j=_nStCnt-1; j>=0; --j)
  {
   if(_eArr[j] > _e)
   {
    _eArr[j+1] = _eArr[j]; // 往后移
   }
   else
   {
    break;
   }
  }
  _eArr[j+1] = _e; // 将该元素放置正确位置上
 }
 
 _declspec(dllexport) void InsertSort(int _eArr[], int _nCnt)
 {
  // 从  第二个开始,把他们依次插入到有序的序列中去
  for(int i=1; i<_nCnt; ++i)
  {
   InsertOne(_eArr, i, _eArr[i]);
  }
 } 

3). 编译

4). 创建一个单文档程序, 使用DLL (mfc程序使用)

5). 重写 OnDraw 函数, 添加声明
 
 void InsertSort(int _eArr[], int _nCnt)
 
 void CCM21_DllTestDocView::OnDraw(CDC* pDC)
 {
  CCM21_DllTestDocDoc* pDoc = GetDocument();
  ASSERT_VALID(pDoc);
  // TODO: add draw code for native data here
 
  int arr_nNum[5] = {10, 20, 6, 18, 12};
  InsertSort(arr_nNum, 5);
  CString str;
  str.Format("%d, %d, %d, %d, %d", arr_nNum[0],
   arr_nNum[1],arr_nNum[2],arr_nNum[3],arr_nNum[4]);
  pDC->TextOut(0, 0, str);
 }

6). 隐式加载方式 加载 DLLExm2.lib
 拷贝 DLLExm2.dll, DLLExm2.lib 到目录下

7). C++程序也可以使用, 步骤同上 (c语言不能直接使用)
(
 C语言参见:
  #ifdef __cplusplus
  #define EXPORT extern "C" __declspec (dllexport)
  #else
  #define EXPORT __declspec (dllexport)
  #endif
)

实例2:
  导出类

1). 添加类 CPerson ( Insert->New class  )
2). 导出类
  在类名和class之间加VC的关键字 _declspec(dllexport)

3). 单文档类使用 导出类
 拷贝头文件到目录下
 
 1> 添加头文件 Person.h
 2> 使用即可
   Person p;

实例3:
  添加全局函数 ( .h, .cpp 文件 )

1). 添加导出的全局函数
Fun.h
 _declspec(dllexport) void a();
 _declspec(dllexport) void b();
Fun.cpp
 #include "stdafx.h" // 注意此行include必须添加到第一行
 #include "Fun.h"
 void a()
 {
 }
 void b()
 {
 }

2).  使用全局函数 
方式1:
 只添加头文件即可
  #include "Fun.h"
 
方式2:
 只添加函数声明即可
  void a();
  void b();


实例4:
 dll 直接可以互相使用

步骤:
1). 建立 dll 项目 DllInner, 添加类 CMyClass
 class _declspec(dllexport) CMyClass 
 {
 public:
  CMyClass();
  virtual ~CMyClass();
  int GetData();
 };
 // .cpp
 CMyClass::CMyClass()
 {

 }
 CMyClass::~CMyClass()
 {

 }
 int CMyClass::GetData()
 {
  return 1000;
 }

2). 建立第二个dll项目 DllSmd,  添加类 CPerson, 并使用 CMyClass 类
 1> 编写CPerson
 class _declspec(dllexport)  CPerson 
 {
 public:
  CPerson();
  virtual ~CPerson();
  int Fun();
 };

 //.cpp
 #include "MyClass.h"
 CPerson::CPerson()
 {

 }
 CPerson::~CPerson()
 {

 }
 int CPerson::Fun()
 {
  CMyClass myClass;
  return myClass.GetData();
 }
 
 2> 添加dll文件
  Setting -> DllInner.lib
 3> 拷贝 MyClass.h, DllInner.dll, DllInner.lib 到当前目录

3). 建立测试程序使用 dll项目 DllSmd (c++)
 
 1> 添加Setting -> DllSmd.lib
 2> #include "Person.h"
 3> 将 DllSmd.lib, DllSmd.dll,  DllInner.dll, DllInner.lib 拷贝到当前目录

4). 运行测试程序


========
隐式加载方式
方式二:
 在stdafx.h文件中添加代码:
 #pragma comment(lib,”M21_DllExm.lib”)
 注意: 将.lib文件放到当前目录下

Win32下的

(1)Win32 DLL 完成 DLL 导出两个函数.txt


实例:
  Win32 DLL 完成 DLL 导出两个函数  ( MFC,C++程序均可以使用, C程序不能使用 )

1. 建立一个 DLL 文件
 new -> project -> Win32 DLL -> DLLTest
2. 建立一个空项目
3. 添加一个 dll1.cpp, 编写两个函数
 _declspec(dllexport) int Add(int x,int y)
 {
  return x+y;
 }
 _declspec(dllexport) int Subtract(int x,int y)
 {
  return x-y;
 }
4. 编译
5. 查看 dll 文件中包含的信息
  C:\Program Files\Microsoft Visual Studio\VC98\Bin\下找到VCVARS32.bat 命令行运行
  cd Debug
  dumpbin -exports dll1.dll 

6. 建立测试程序 DLLTestDLg, 基于对话框程序
7. 放置两个按钮add, aubtract, 调用两个函数
 void CDLLTestDLg::OnBtnAdd()
 {
   // TODO: Add your control notification handler code here
   CString str;
   str.Format("3+5=%d",Add(3,5));
   MessageBox(str);
 }
 void CDLLTestDLg::OnBtnSubtract()
 {
   // TODO: Add your control notification handler code here
   CString str;
   str.Format("5-3=%d",Subtract(5,3));
   MessageBox(str);
 }

8. 添加函数声明
 extern int Add(int x,int y);
 extern int Subtract(int x,int y);
  
可以使用标示符表示这两个函数是从动态链接库的.lib文件引用的,以生成效率更高的代码
 _declspec(dllimport) int Add(int x,int y);
 _declspec(dllimport) int Subtract(int x,int y);

9. 设置隐式调用
 Project->Setting->Link->Object/Library Modules -> DLLTest.lib

10. 拷贝 Dll1.lib和Dll1.dll 拷贝到当前目录下
 如果要查看 DllTest.exe 文件信息,使用命令行 dumpbin -imports dlltest.exe

-------------
添加.h头文件

11. 修改 DLL 项目, 添加 dll1.h, 在其中添加 函数声明, 用一组宏来取代_declspec(dllimport)

dll1.h:
 #ifdef DLL1_API
 #else
 #define DLL1_API extern "C" _declspec(dllimport)
 #endif
 
 DLL1_API int _stdcall Add(int a,int b);
 DLL1_API int _stdcall Subtract(int a,int b);
 
dll1.cpp
 #define DLL1_API extern "C" _declspec(dllexport)
 #include "Dll1.h"
 #include <Windows.h>
 #include <stdio.h>
 
 int _stdcall Add(int a,int b)
 {
  return a+b;
 }
 
 int _stdcall Subtract(int a,int b)
 {
  return a-b;
 }

12. 修改对话框程序
 1> 删除函数声明
 2> 添加头文件
   #include "dll1.h"

-------------
编写一个C++程序, 也可以使用上述函数

 

(2)Win32 DLL 完成 DLL 导出两个函数-C语言.txt


在 Visual C++ 中,工作空间(workspaces)和项目(projects)不同。
项目通常与建立的应用程序(.exe)或者动态链接库(.dll)相联系。一个工作空间可以包含一个或多个项目。

实例:
 建立DLL, 建立测试程序 (WIN32 DLL) (mfc,c/c++均可以使用)

1). 新建 Workspace
 File -> New -> Workspaces -> 输入Workspace Name (Li9_1)

2). 在 Workspace 下新建项目
 File -> New -> Projects -> Win32 Dynamic-Link Library
  -> 选中单选按钮Add To Current Workspace
  -> Project Name (Li9_1Lib)
  -> Location 栏删除Li9_1Lib子目录以便项目建立在Li9_1 目录
  -> An Empty DLL Project

3). 添加文件
 Li9_1Lib.h
  /*-----------------------------------------
  Li9_1Lib.h header file
  ------------------------------------------*/
  #ifdef __cplusplus
  #define EXPORT extern "C" __declspec (dllexport)
  #else
  #define EXPORT __declspec (dllexport)
  #endif
  EXPORT int Add(int x, int y);

 Li9_1Lib.c
  /*---------------------------------------
  Li9_1Lib.c
  -----------------------------------------*/
  #include <windows.h>
  #include "Li9_1Lib.h"
  int WINAPI DllMain ( HINSTANCE hInstance, DWORD fdwReason, PVOID
  pvReserved)
  { return TRUE ; }
  EXPORT int Add(int x, int y)
  { return (x+y); }

 Release 或按 Debug, 建立Li9_1Lib.dll
  Li9_1Lib.lib(动态链接库的引用库), Li9_1Lib.dll(动态链接本身)

这两个文件中定义了 EXPORT 宏。
DLL 中应用程序使用的函数必须是输出(exported)的。即确保函数名添加到Li9_1Lib.lib 库中(以便链接程序在链接使用此函数的应用程序时,能够解析出函数名称),而且该函数在Li9_1Lib.dll 中也是找得到的

4). 建立测试程序 ( 在mfc程序中使用 )
 在工作空间 Li9_1 中建立第二个项目Li9_1Test,并且该项目使用Li9_1Lib.dll 文件导出的函数

 File -> New -> Projects -> MFC AppWizard(exe)
  -> Add To Current Workspace
  -> Li9_1Test ( 再在Locations 栏删除Li9_1Test 子目录 )
  -> Dialog based -> Finish

5). 添加按钮
 IDC_BNT_Add  "Add"
 void CLi9_1TestDlg::OnBNTAdd()
 {
  int x=5,y=3;
  CString str;
  str.Format("%d",Add(x,y));
  AfxMessageBox(str);
 }

5). 在 Dlg.h 中引入 dll
 // CLi9_1TestDlg dialog
 #ifdef __cplusplus
 #define IMPORT extern "C" __declspec (dllimport)
 #else
 #define IMPORT __declspec (dllimport)
 #endif
 IMPORT int Add(int x, int y);

 class CLi9_1TestDlg : public CDialog
 { …}

6). 设置 Project -> Settings 选项
 1). General, ,确保项目Li9_1Lib 和项目Li9_1Test 编译生成的中间文件(Intermediate files)和最终输出文件(Output files)在同一个目录下。
  D:\C++_Test\Li9_1
 
 2). Project -> Dependencies
  使项目Li9_1Test 依赖项目Li9_1Lib 的输出

7). 运行程序


 

 

 

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值