zoukankan      html  css  js  c++  java
  • VC2008如何生成及使用DLL(图文并茂,完整版)

     

    生成、使用DLL看起来简单,但做起来才发现还是有一些地方需要注意的。

    1. 打开VS2008,新建一个VC工程,选择Win32类型,Win32项目:

    建立VC Win32工程

    2. 应用程序类型选择DLL,附加选项选择到处符号,公共头文件不要选择,然后点完成即可。

    3. 工程生成后需要修改属性,在配置属性的常规选项中将MFC的使用修改为“静态库中使用MFC”。

    注意,这一步是必须的,否则写出来的DLL将需要在有VC2008的环境上才能运行。

    4. 关注自动生成的文件MyDllTest.cpp,其中有几个实例,可以将他们删除,也可以不管他们。

    5. 添加自己的接口,如:GetMyDllVersion

    ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
    1. // 得到当前DLL的版本号
    2. MYDLLTEST_API UINT32 GetMyDllVerion(VOID )
    3. {
    4. return 1234;
    5. }

    6. 在头文件MyDllTest.h中添加声明

    ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
    1. MYDLLTEST_API UINT32 GetMyDllVerion( VOID );

    7. 添加导出符号定义文件,理论上是可以不要导出定义的,但是那样的结果就是生成的DLL中的符号名字不明确,只有定义了导出符号,才可以使得DLL中的借口函数名称得以确定。(关于def与dll 请参阅msdn)

     
    文件内容:
    ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
    1. LIBRARY "MyDllTest"
    2. EXPORTS
    3. GetMyDllVerion

    8. 在项目属性中设置模块定义文件为刚才建立的symexport.def文件:

    设置DLL的输出符号定义文件

    9. 生成,可以得到一个MyDllTest.dll,使用Depends工具(VC6.0自带)可以查看这个DLL中包含了多少接口以及接口名:

    使用Depends工具查看DLL接口

    会发现除了我们定义的借口GetMyDllVersion外还有几个??开头的接口,他们就是那些没有在模块定义文件中定义的借口自动生成的。

    10. 除了DLL外我们还会发现生成了MyDllTest.lib文件,这个lib文件可以在其他的程序使用这个DLL的时候将其连接进去,同时只要包含MyDllTest.h即可调用这个DLL中的借口了。

    如何引入dll

    方法一.装载期间动态加载。(需要lib和dll)

    1。新建Win32应用程序空项目。

    2。把生成的dll、lib这2个文件复制到新建的目录下。

    3。添加导入库:工具--项目和解决方案(vs里是options)--VC++目录,选择右侧“显示以下内容的目录”下的“库文件”,把lib所在目录添加。

    4。头文件: MyDllTest.h(与编写DLL中一样)

    5。源文件:main.c

    可注释#pragma comment(lib," MyDllTest.lib")这条,但必须设置链接库,方法:

    右击项目--属性--配置属性--链接器--输入--附加依赖项: MyDllTest.lib

    1. #include " MyDllTest.h"
    2. #include " windows.h"
    3. #pragma comment(lib," MyDllTest.lib")
    4. int WINAPI WinMain(__in HINSTANCE hInstance, __in_opt HINSTANCE hPrevInstance, __in_opt LPSTRlpCmdLine, __in int nShowCmd )
    5. {
    6. GetMyDllVersion();
    7. return 0;
    8. }

    方法二:运行期间动态加载。(只需Dll文件即可)

    需要使用 Windows API 函数: LoadLibrary 、GetProcAddress 以及 FreeLibrary


    #include <iostream>

    #include <windows.h>
    using namespace std;
    //定义FunctionFunc为指向一个返回值为int型 无参数的函数的指针
    typedef int (*FunctionFunc)();

    int main()
    {
    FunctionFunc _FunctionFunc;
    //加载目标Dll
    HMODULE hModule = ::LoadLibrary (TEXT("D:MyDllTest.dll"));
    if (hModule==NULL)//如果Dll加载失败,释放它占用的资源
    {
    ::FreeLibrary(hModule);
    }
    //取得目标Dll中导出函数的地址(提醒:函数名就是函数的入口地址)
    _FunctionFunc=(FunctionFunc)::GetProcAddress (hModule,"GetMyDllVersion");
    if (_FunctionFunc==NULL)
    {
    ::FreeLibrary (hModule);
    }
    int a =_FunctionFunc();
    cout<< a<<endl;
    ::FreeLibrary(hModule);
    cin.get();
    return 1;

    }

    有时候我们拿到的是别人的DLL和头文件,但是却没有LIB文件,这时就要使用另外的方法调用DLL中的接口了,例如MD5接口的使用:

    ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
    1. // 按照MSDN中的说明定义函数原型如下
    2. typedef struct
    3. {
    4. ULONG i[2];
    5. ULONG buf[4];
    6. unsigned char in[64];
    7. unsigned char digest[16];
    8. } MD5_CTX;
    9. typedef void (CALLBACK* MD5Init_Tpye)(MD5_CTX* context);
    10. typedef void (CALLBACK* MD5Update_Tpye)(MD5_CTX* context,
    11. unsigned char* input,
    12. unsigned int inlen);
    13. typedef void (CALLBACK* MD5Final_Tpye)(MD5_CTX* context);
    ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
    1. // 使用MD5接口
    2. HINSTANCE hDLL;
    3. // MD5接口是在Cryptdll.dll中的
    4. hDLL = LoadLibrary(TEXT("Cryptdll.dll" ));
    5. MD5Init_Tpye MD5Init;
    6. MD5Update_Tpye MD5Update;
    7. MD5Final_Tpye MD5Final;
    8. // 得到接口指针
    9. MD5Init = (MD5Init_Tpye)GetProcAddress(hDLL, "MD5Init");
    10. MD5Update = (MD5Update_Tpye)GetProcAddress(hDLL, "MD5Update");
    11. MD5Final = (MD5Final_Tpye)GetProcAddress(hDLL, "MD5Final");
    12. if (!MD5Init || !MD5Update || !MD5Final)
    13. {
    14. // 取得接口指针失败
    15. FreeLibrary(hDLL);
    16. return ;
    17. }
    18. MD5_CTX md5_context;
    19. MD5Init(&md5_context);
    20. MD5Update(&md5_context, src, length);
    21. MD5Final(&md5_context);
    22. // 不要忘记释放导入的DLL
    23. FreeLibrary(hDLL);

    http://blog.sina.com.cn/s/blog_a401a1ea010174rr.html

  • 相关阅读:
    004 使用文本编辑器
    003 第一个Python程序
    002 Python解释器
    001 安装Python
    000 Python教程
    001 Java环境变量配置
    002 基础语法1
    003 基础语法2
    dede首页调用会员积分和头像代码
    DEDE 会员调用方法
  • 原文地址:https://www.cnblogs.com/findumars/p/5176338.html
Copyright © 2011-2022 走看看