VC ++链接库(三)非MFC动态库

    非MFC动态库指的是不用MFC的类库结构,直接用C语言写的DLL,其导出的函数是标准的C接口,能被非MFC或MFC编写的应用程序所调用

     在VC++6.0中,File-->New-->Win32 Dynamic-Link Library创建非MFC动态库

(一)一个简单的非MFC动态库                                                           


    在VC++中new一个Win32 Dynamic-Link Library工程DllTest。注意不要选择MFC AppWizard(dll),因为用MFC AppWizard(dll)建立的将是后面要讲述的MFC 动态链接库。 
 
    在建立的工程中添加DllTest.h及DllTest.cpp文件,源代码如下:
//DllTest.h文件
#ifdef DLL_API
#else
#define DLL_API extern "C" _declspec(dllimport) // 需要在每个要导出的函数前面添加标示符 _declspec(dllimport)
                                                                         //用DLL_API代替_declspec(dllimport)
                                                                      //一般添加 extern "C"解决名字改编问题
#endif

DLL_API int add(int a,int b);
DLL_API int subtract(int a,int b);

//DllTest.cpp文件
#define DLL_API extern "C" _declspec(dllexport)   //这里是_declspec(dllexport) 
#include "DllTest.h"

#include <Windows.h>
#include <stdio.h>

int add(int a,int b)
{
     return a+b;
}

int subtract(int a,int b)
{
     return a-b;
}
直接编译就产生了.lib .dll文件

(二)隐式链接的方式加载DLL                                                           

      再新建一个工程Test(我们随便建一个win32 console Application),该工程只有一个Test.cpp文件它调用DLL中的函数,代码如下:
#include <stdio.h>  
#include "..\DllTest\DllTest.h"
//#pragma comment( lib, "..\\DllTest\\Debug\\DllTest.lib" )  
int main(int argc, char *argv[])  
{  
    
     printf("%d\n",add(5,3));
     return 0;  
}  
如何隐式加载,下面我们一步步的分析,
       直接build会出错  Test.obj : error LNK2001: unresolved external symbol __imp__add,,有链接的时候出错,解决:在Test程序中,选择Project-->Settings-->ling-->Object/library modules中输入DllTest.lib(或者在程序中加#pragma comment( lib, "..\\DllTest\\Debug\\DllTest.lib" ) ),然后选择tools-->options-->directories-->library files菜单或选项,填入库文件路径E:\Program Files\Microsoft Visual Studio 6.0\MyProjects\DllTest\Debug(或者直接将产生的DllTest.lib文件拷贝到Test工程下),重新build没有问题了。
      运行,出错提示计算机中丢失DllTest.dll,那么我们就需要将产生的DllTest.dll文件拷贝到Test工程目录下,重新运行成功
                              


(三)声明导出函数                                                                        

      在刚才的例子中给出的是在函数声明前面加上_declspec(dllimport),同时在前面加上了extern "C"
           注:1.编译器在生成DLL时,会对导出的函数进行名字改编,使用不同的编译器分别生成DLL和访问该DLL的客户端程序的话,后者在访问该DLL的导出函数时就会出现问题,所以一般在定义导出函数时,加上限定符extern "C"
                 2.使用extern "C"可以解决C++和C语言之间互相调用时函数命令的问题,但是不能用于导出一个类的成员函数,只能用于导出全局函数这种情况
                 3.如果函数的调用约定发生了改变,即使使用了extern "C",它们的名字仍然会发生改变,那么就有了第二周声明导出函数的方式,使用模块文件(DEF)
       接着我们将声明导出函数的另外一种方法,使用模块文件

      下面我们重新建Win32 Dynamic-Link Library工程DllTest,添加DllTest.cpp文件,代码如下:
int add(int a,int b)
{
     return a+b;
}

int subtract(int a,int b)
{
     return a-b;
}
 
      然后添加模块定义文件DllTest.def,我们可以在DllTest工程目录下新建一个空的文本取名DllTest.def,然后在[Project\Add To Project\Files...]-->Insert Files into Project,选择DllTest.def文件将其添加进Test工程,然后添加代码:
LIBRARY DllTest//LIBRARY指定动态链接库的内部名称,这个必须要和生成的动态链接库名称匹配

EXPORTS//指明DLL要导出的函数
add
subtract
build 这个DllTest工程,就产生了.lib .dll文件

自己再编译一个测试工程,代码如下:
#include <stdio.h>  
#include <windows.h> 
//typedef int(*lpAddFun)(int, int); // 宏定义函数指针类型
int add(int a, int b);
int subtract(int a , int b);

int main(int argc, char *argv[]) 
{ 
        printf( "%d\n" ,add(5,3));
        printf( "%d\n" ,subtract(5,3));
    return 0; 
 } 
要像刚才隐式加载一样的去做,才能运行成功

(四)显示加载DLL                                                                                 

       上面使用的都是隐式加载DLL的方法,对动态链接库的访问还可以使用显示加载方式:完全由编程者用API函数加载和卸载DLL,程序员可以决定 DLL 文件何时加载或不加载,显式链接在运行时决定加载哪个DLL文件

   第一步还是创建DllTest工程,产生.lib .dll文件,
   第二步新建工程Test(我们随便建一个win32 console Application),代码如下:
//Test.cpp
#include <stdio.h>
#include <Windows.h>
typedef int (*ADDPROC)(int ,int );//定义函数指针类型

int main(int argc,char *argv[])
{
     HINSTANCE hInst;
     ADDPROC Add;
     hInst=LoadLibrary("..\\DllTest\\Debug\\DllTest.dll");  //动态加载DLL
     if(hInst!=NULL)
     {
          Add=(ADDPROC)GetProcAddress(hInst,"add");//获取DLL的导出函数
          if(Add!=NULL)
          {
               int result=Add(5,3);
               printf("%d\n",result);
          }
          FreeLibrary(hInst);
     }
     return 0;
}





  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值