zoukankan      html  css  js  c++  java
  • c++动态库封装及调用(3、windows下动态库调用)

    1.DLL的隐式调用

    隐式链接采用静态加载的方式,比较简单,需要.h、.lib、.dll三件套。新建“控制台应用程序”或“空项目”。配置如下: 
    项目->属性->配置属性->VC++ 目录-> 在“包含目录”里添加头文件testdll.h所在的目录 
    项目->属性->配置属性->VC++ 目录-> 在“库目录”里添加头文件testdll.lib所在的目录 
    项目->属性->配置属性->链接器->输入-> 在“附加依赖项”里添加“testdll.lib”(若有多个 lib 则以空格隔开) 。 //你也可以在代码中添加一行设置库的链接,#pragma comment(lib, "DLLSample.lib")

    库文件头文件等目录设置,本文将库文件及头文件拷贝到工程目录下DLL文件夹下

    添加LIB依赖项

     #调用的源程序#

    // callmyDLL.cpp : 定义控制台应用程序的入口点。  
    //包含头头文件,函数声明    
      
    #include "stdafx.h"  
    #include "stdlib.h"  
    #include "myDLL.h"  
      
    int _tmain(int argc, _TCHAR* argv[])  
    {  
      //这是通过上节的extern方式调用的
    int z= Add(1,2);
      
      //也可以通过类导出的方式调用
      //CmyDll dll;
      //int z = dll.Add(1,2);
    printf(
    "z is:%d ", z); system("pause"); return 0; }

    以上如果包含目录、库目录、库的依赖项都没有问题就可以生成成功了

    运行时最后一步:将动态库文件拷贝到可执行文件目录下,否则会出现如下错误。

    如何没有设置lib目录和依赖项,可以在代码中添加以下一行代码也可以生成成功

    // callmyDLL.cpp : 定义控制台应用程序的入口点。  
    //包含头头文件,函数声明    
      
    #include "stdafx.h"  
    #include "stdlib.h"  
    #include "myDLL.h"  
    #prama comment(lib, "myDll.lib")  
    //此时的myDll.lib的路径必须能找到的,可以给定一个全路径如:“c:\myDll.lib”
    
    int _tmain(int argc, _TCHAR* argv[])  
    {  
        int z= Add(1,2);  
        printf("z is:%d
    ", z);  
        system("pause");  
        return 0;  
    }  

    所以通过设置依赖项和库目录和添加#Prama是具有相同效果的,如果有问题,得检查是否两者的生成平台不同(如win32和x64)或者一个是Debug一个是release

    2、DLL显示调用

    对于显示连接,即动态加载我们需要调用LoadLibrary
    在MSDN中:HMODULE WINAPI LoadLibrary(
      __in  LPCTSTR lpFileName
    );
    它的功能是映射一个可执行模块到调用进程的地址空间。由此我们知道显示调用就是函数指针来调用函数。

    Steps:
    1、声明头文件<windows.h>,说明我想用windows32方法来加载和卸载DLL
    2、然后用typedef定义一个指针函数类型.typedef  void(*fun) //这个指针类型,要和你调用的函数类型和参数保持一致
    3、定一个句柄实例,用来取DLL的实例地址。HINSTANCE hdll;
    格式为hdll=LoadLibrary(“DLL地址”);这里字符串类型是LPSTR,当是unicode字符集的时候会不行,
    因此要在配置-属性-常规里面把默认字符集“unicode”改成支持多字符扩展即可。
    4、取的地址要判断,返回的句柄是否为空,如果为无效句柄,那么要释放加载DLL所占用的内存。
    5、定义一个函数指针,用来获取你要用的函数地址。
      然后通过GetProcAdress来获取函数的地址,参数是DLL的句柄和你要调用的函数名:比如:FUN=(fun)GetProcAdress(hdll,"sum");
      这里也要判断要函数指针是否为空,如果没取到要求的函数,那么要释放句柄。
    6、然后通过函数指针来调用函数。
    7、调用结束后,就释放句柄FreeLibrary(hdll);

    直接上代码,一一一一一目了然

    // callDLLSee.cpp : 定义控制台应用程序的入口点。  
    //通过调用windowsAPI 来加载和卸载DLL  
    #include "stdafx.h"  
    #include "Windows.h"  
    typedef int(*Dllfun)(int , int);  
      
    int _tmain(int argc, _TCHAR* argv[])  
    {  
        Dllfun funName;  
        HINSTANCE hdll;  
        //put DLL under the Debug path   
        //use   _T 设置为宽字符  
        hdll = LoadLibrary( _T("myDLL.dll"));  
        if (hdll == NULL)  
        {  
            FreeLibrary(hdll);  
        }  
        funName = (Dllfun)GetProcAddress(hdll, "Add");  
        if (funName == NULL)  
        {  
            FreeLibrary(hdll);  
        }  
        int x = 1, y = 10;  
        double z= funName(r, h);  
        printf("z= %d
    ", z);  
      
        FreeLibrary(hdll);  
        return 0;  
    } 

    参考此系列:http://www.cppblog.com/suiaiguo/archive/2016/01/28/90619.html#212749

  • 相关阅读:
    【洛谷】P1303 A*B Problem(高精度乘法模板)
    快速幂
    【洛谷】P1601 A+B Problem 高精(高精度加法模板)
    进制转换
    【洛谷】P1551 亲戚(并查集模板)
    求最大公约数的两种方法
    快速排序
    异或交换两个数
    数字字符串互相转换的三种方法
    Hello world(我来啦)
  • 原文地址:https://www.cnblogs.com/marblemm/p/7804056.html
Copyright © 2011-2022 走看看