zoukankan      html  css  js  c++  java
  • VS---《在VS2010中 使用C++创建和使用DLL》(002)

    VS---《在VS2010中 使用C++创建和使用DLL》(002)

      前面初认识了创建和调用DLL,在VS工程下可以通过在 同一工程、不同工程 下创建和调用DLL。现在,同一工程下创建和调用DLL,实现三种方式的创建和调用DLL:

    (1)加载时动态链接方式调用DLL---用到_declspec(dllimport)

    (2)运行时动态链接方式调用DLL---用到LoadLibrary()

    (3)以.def文件(模块定义文件)方式导出函数

       按其它方式,也可以分为:

    (1)静态调用DLL:添加“XXX.lib”,然后#include "XXX.h",把XXX.lib(引入库文件)、XXX.DLL(动态库文件)、XXX.h(头文件)全部放到工程目录下。

    (2)动态调用DLL:通过LoadLibrary、GetProcAddress、FreeLibrary实现。

    **********************************************************************************************

    **********************************************************************************************

    **********************************************************************************************

    **********************************************************************************************

    //====================================================================
    // 文件: DellDemo.h
    //====================================================================
    
    #ifndef _DLL_H_
    #define _DLL_H_
    
    #ifdef DLLProvider
    #define EXPORTS_DELL_DEMO _declspec( dllexport )
    #else
    #define DLL_EXPORT_IMPORT _declspec(dllimport)
    #endif
    extern "C" DLL_EXPORT_IMPORT int Add (int a , int b);
    #endif
    
    /*
    #ifndef _MYCODE_H_
    #define _MYCODE_H_
    #ifdef DLLDEMO1_EXPORTS
    #define EXPORTS_DEMO _declspec( dllexport )
    #else
    #define EXPORTS_DEMO _declspec(dllimport)
    #endif
    extern "C" EXPORTS_DEMO int Add (int a , int b);
    #endif
    */
    //====================================================================
    // 文件: DellDemo.cpp
    //====================================================================
    
    #include "DellDemo.h"
    int Add ( int a , int b )
    {
        return ( a + b );
    }
    /*
        作者:WP @20160627
        功能:学习制作DLL、调用DLL。
              test_Dell.cpp : 定义控制台应用程序的入口点。
        方法:
              (1)加载时动态链接方式调用DLL---用到_declspec(dllimport)
              (2)运行时动态链接方式调用DLL---用到LoadLibrary()
              (3)以.def文件(模块定义文件)方式导出函数
    */
    
    //-------------------------------(1)加载时动态链接方式调用DLL-------------------------
    //在提供者那里, 方法被声明为__declspec(dllexport)
    //在使用者那里,方法被声明为__declspec(dllimport)
    #include <iostream>
    #include <windows.h>
    #include <tchar.h>
    #include <stdio.h>
    
    //#include "..\Dell_001\DellDemo.h"
    using namespace std;
    
    //注意:导入库文件的目录必须在本工程的目录下,也就是说要把生成的dll和lib文件都要拷贝到该工程的目录下,
    //因为不再该目录下,尽管修改了路径,仍然提示找不到DllDemo.dll
    #pragma comment(lib, "..\debug\Dell_001.lib")              //添加lib路径    
    extern "C" _declspec(dllimport) int Add(int a, int b);    //DLL输出:提供者申明 + 输出函数名
    
    int _tmain(int argc, _TCHAR* argv[])
    {
            cout<<Add(2, 3)<<endl;
            while(1);//程序运行到这,方便看运行结果
                return 0;
    }
    /*
        作者:WP @20160627
        功能:学习制作DLL、调用DLL。
              test_Dell.cpp : 定义控制台应用程序的入口点。
        方法:
              (1)加载时动态链接方式调用DLL---用到_declspec(dllimport)
              (2)运行时动态链接方式调用DLL---用到LoadLibrary()
              (3)以.def文件(模块定义文件)方式导出函数
    */
    
    //-------------------------------(2)运行时动态链接方式调用DLL---用到LoadLibrary()-------------------------
    #include <iostream>
    #include <windows.h>
    #include <tchar.h>
    #include<stdio.h>
    
    using namespace std;
    
    typedef int (*AddFunc)(int a, int b);
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
        HMODULE hDll = LoadLibrary(_T("Dell_002.dll"));
        if (hDll != NULL)
        {
            AddFunc add = (AddFunc)GetProcAddress(hDll, "Add");
            if (add != NULL)
            {
                cout<<add(2, 3)<<endl;
            }
            FreeLibrary(hDll);
        }
        while(1);
    }

    DellDemo.def

    LIBRARY  "Dell_003"
    EXPORTS
    Add @1;Export the Add function
    /*
        作者:WP @20160627
        功能:学习制作DLL、调用DLL。
              test_Dell.cpp : 定义控制台应用程序的入口点。
        方法:
              (1)加载时动态链接方式调用DLL---用到_declspec(dllimport)
              (2)运行时动态链接方式调用DLL---用到LoadLibrary()
              (3)以.def文件(模块定义文件)方式导出函数
    */
    
    //-------------------------------(3)以.def文件(模块定义文件)方式导出函数-------------------------
    #include <iostream>
    #include <windows.h>
    #include <tchar.h>
    #include<stdio.h>
    
    using namespace std;
    
    typedef int (*AddFunc)(int a, int b);
    int _tmain(int argc, _TCHAR* argv[])
    {
        HMODULE hDll = LoadLibrary("Dell_003.dll");
        if (hDll != NULL)
        {
            AddFunc add = (AddFunc)GetProcAddress(hDll, MAKEINTRESOURCE(1));
            if (add != NULL)
            {
                cout<<add(2, 3)<<endl;
            }
            FreeLibrary(hDll);
        }
        while(1);
    }


    其中几点注意:
    (1)Module-Definition File(.def)文件的格式如下:
        LIBRARY语句说明.def文件对应的DLL;
        EXPORTS语句后列出要导出函数的名称。可以在.def文件中的导出函数名后加@n,表示要导出函数的序号为n(在进行函数调用时,这个序号有一定的作用)。
        
    模块定义文件中的库文件名应和工程名一致。
    LIBRARY  "DllDemo"   //这里的字符串名和工程名要一致, 注意这句注释不能放进xxx.def文件中,否则报错
    EXPORTS
    Add @1;Export the Add function

    (2)字符集的问题(是Unicode字符集还是多字节集),两种方案,一种修改字符集为多字节集,二是将字符串前面加 _T("").
      error C2664: “LoadLibraryW”: 不能将参数 1 从“const char *”转换为“LPCWSTR”

    在使用VS2010编写运行时动态链接dll文件时出现的一个问题,问题解决得益于此文章:http://blog.sina.com.cn/s/blog_6a2236590100xbgl.html
    通过调用这个函数:
    LoadLibrary出现的该问题。
    原因 :工程只支持UNICODE字符
    解决方法:
    1、在解决方案资源管理器中的工程上右键属性->配置属性-->常规--->字符集---->使用多字节符字符集
    2、也就是宽字符,所以下面这行代码,应该编译有错误
    hinst=LoadLibrary("InTheHand.Net.Personal.dll");
    也就是:
    cannot convert parameter 1 from 'char [27]' to 'const unsigned short *'
    改为:
    hinst=LoadLibrary(L"InTheHand.Net.Personal.dll");
    或者
    hinst=LoadLibrary(_T("InTheHand.Net.Personal.dll"));

     感谢:http://blog.sina.com.cn/s/blog_6a2236590100xbgl.html ; https://www.cnblogs.com/holyprince/p/4236586.html

  • 相关阅读:
    pagination分页插件使用
    ajax实现图片文件上传和图片预览
    屏幕护眼色调调节
    css画三角形以及实现带三角的阴影效果
    软件测试homework3
    使用Junit包进行单元测试并导入eclemma包。
    软件测试homework2
    软件测试homework1 编程过程的一个小错误
    ReentrantLock
    Elasticsearch-基本概念
  • 原文地址:https://www.cnblogs.com/carle-09/p/11098231.html
Copyright © 2011-2022 走看看