zoukankan      html  css  js  c++  java
  • C/C++中动态链接库的创建和调用

    C/C++中动态链接库的创建和调用

    DLL 有助于共享数据和资源。多个应用程序可同时访问内存中单个DLL 副本的内容。DLL 是一个包含可由多个程序同时使用的代码和数据的库。下面为你介绍C/C++中动态链接库的创建和调用。

    动态连接库的创建步骤:

    创建Dll有两种方式。

    一、创建Non-MFC DLL动态链接库

    1、打开File —> New —> Project选项,选择Win32 Dynamic-Link Library —>sample project —>工程名:DllDemo

    2、新建一个。h文件DllDemo.h

    复制代码
    #ifdef DllDemo_EXPORTS   
    #define DllAPI __declspec(dllimport)   
    #else   
    #define DllAPI __declspec(dllexport)  
    extern "C" //原样编译   
    { 
        DllAPI int __stdcall Max(int a,int b); //__stdcall使非C/C++语言内能够调用API   
    }  
    #endif 
    复制代码

    3、在DllDemo.cpp文件中导入DllDemo.h文件,并实现Max(int,int)函数 

    复制代码
    #include "DllDemo.h"
    DllAPI int __stdcall Max(int a,int b)   
    { 
         if(a==b)   
             return NULL;   
         else if(a>b)   
             return a;   
         else   
             return b;   
    }     
    复制代码

    4、编译程序生成动态连接库

    二、用.def文件创建动态连接库DllDemo.dll

    1、删除DllDemo工程中的DllDemo.h文件。

    2、在DllDemo.cpp文件头,删除 #include DllDemo.h语句。

    3、向该工程中加入一个文本文件,命名为DllDemo.def并写入如下语句:

    1. LIBRARY MyDll  
    2. EXPORTS  
    3. Max@1 

    4、编译程序生成动态连接库。

    动态链接的调用步骤:

    一、隐式调用

    1、建立DllCnslTest工程

    2、将文件DllDemo.dll、DllDemo.lib拷贝到DllCnslTest工程所在的目录

    3、在DllCnslTest.h中添加如下语句:

    复制代码
    #define DllAPI __declspec(dllimport)   
    #pragma comment(lib,"DllDemo.lib") //在编辑器link时,链接到DllDemo.lib文件   
    extern "C"   
    {   
    DllAPI int __stdcall Max(int a,int b);   
    }  
    复制代码

    4、在DllCnslTest.cpp文件中添加如下语句: #include "DllCnslTest.h"//或者 #include "DllDemo.h"

    复制代码
    void main()   
    {   
          int value;   
          value = Max(2,9);   
          printf("The Max value is %d
    ",value);   
    }  
    复制代码

    5、编译并生成应用程序DllCnslTest.exe

    二、显式调用

    1、建立DllWinTest工程。

    2、将文件DllDemo.dll拷贝到DllWinTest工程所在的目录或Windows系统目录下。

    3、用vc/bin下的Dumpbin.exe的小程序,查看DLL文件(DllDemo.dll)中的函数结构。

    4、使用类型定义关键字typedef,定义指向和DLL中相同的函数原型指针。

    例:

    //需要引入头文件  windows.h最好在最前面,否则可能会出错   不需要windef.h  否则会报错  
    #include <windows.h>
    #include <iostream>  
    typedef int(__stdcall  *lpMax)(int a,int b); //此语句可以放在.h文件中  必须声明为__stdcall类型 否则出错

    5、通过LoadLibray()将DLL加载到当前的应用程序中并返回当前DLL文件的句柄。

    例:

    HINSTANCE hDll; //声明一个Dll实例文件句柄   
    hDll = LoadLibrary("DllDemo.dll");//导入DllDemo.dll动态连接库  

    6、通过GetProcAddress()函数获取导入到应用程序中的函数指针。

    例:

    复制代码
    lpMax M;   
    M = (lpMax)GetProcAddress(hDLL,"Max");   
    int value;   
    value = M(2,9);   
    std::cout<<value<<std::endl;  
    复制代码

    注:上述代码中 Max = (lpMax)GetProcAddress(hDLL,"Max"); 其中参数”Max"为函数名称,可能无法找到(可能和未使用模块定义文件有关)。此时,可用两种方法解决

          1、利用vs自带的命令行工具,查看函数的正确名称,首先cd 到bin目录(vc/bin),利用的是vs自带的dumpbin.exe工具。进入bin目录之后,输入命令dumpbin /exports d:路径xxx.dll,查看函数的输出名称。通常为_FunctionName@数字,此例中的名称为_Max@8.

      2、根据函数在dll(生成dll的头文件中的顺序),例如 Max = (lpMax)GetProcAddress(hDLL,(LCPSTR)MAKEINTRESOURCE(1)); \找到第一个函数

    7、函数调用完毕后,使用FreeLibrary()卸载DLL文件。

    FreeLibrary(hDll); 

    8、编译并生成应用程序DllWinTest.exe

    注:显式链接应用程序编译时不需要使用相应的Lib文件。

    动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。通过使用 DLL,程序可以实现模块化,由相对独立的组件组成。希望通过本文的分析,你会对此有了解。

     实例源码 

  • 相关阅读:
    Oracle 安装报错 [INS-06101] IP address of localhost could not be determined 解决方法输入日志标题
    Linux下安装oracle数据库提示DISPLAY not set. Please set the DISPLAY and try again。
    redhat 关机注销命令详解
    VirtualBox的四种网络连接方式
    修改RedHat的系统显示时间
    insufficient memory to configure kdump(没有足够的内存)解决方法(待验证、待解决)
    xen坑随笔 heartbeat dpkg垃圾数据库清除
    tomcat 监控脚本
    负载均衡随笔
    GIT命令介绍
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3195558.html
Copyright © 2011-2022 走看看