打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
VS2008 创建DLL和调用DLL
隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中。隐式链接必须的文件:lib .


显式链接是应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,对于解释性语言更为合适。不过实现显式链接要麻烦一些。在应用程序中用LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态链接库调进来,动态链接库的文件名即是上述两个函数的参数,此后再用GetProcAddress()获取想要引入的函数。自此,你就可以象使用如同在应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态链接库。


使用显式链接应用程序编译时不需要使用相应的Lib文件。另外,使用GetProcAddress()函数时,可以利用MAKEINTRESOURCE()函数直接使用DLL中函数出现的顺序号,如将GetProcAddress(hDLL,"Min")改为GetProcAddress(hDLL, MAKEINTRESOURCE(2))(函数Min()在DLL中的顺序号是2),这样调用DLL中的函数速度很快,但是要记住函数的使用序号,否则会发生错误。 


显式链接必须的文件:dll .


一、DLL的创建 (用.def文件创建动态连接库)
创建项目->Win32->Win32项目,名称:MyDLL->选择DLL
1、新建头文件testdll.h
testdll.h代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef TestDll_H_
#define TestDll_H_
#ifdef MYLIBDLL
#define MYLIBDLL extern "C" _declspec(dllimport)
#else
#define MYLIBDLL extern "C" _declspec(dllexport)
#endif
MYLIBDLL int Add(int plus1, int plus2);
//You can also write like this:
//extern "C" {
//_declspec(dllexport) int Add(int plus1, int plus2);
//};
#endif

2、新建源文件testdll.cpp
testdll.cpp代码如下:
1
2
3
4
5
6
7
8
9
#include "stdafx.h"
#include "testdll.h"
#include <iostream>
using namespace std;
int Add(int plus1, int plus2)
{
int add_result = plus1 + plus2;
return add_result;
}

3、新建模块定义文件mydll.def
mydll.def代码如下:
1
2
3
LIBRARY "MyDLL"
EXPORTS
Add @1

4、vs2008自动创建dllmain.cpp文件,它 定义了DLL 应用程序的入口点。

dllmain.cpp代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
      )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
  break;
}
return TRUE;
}
最后,编译生成MyDLL.dll文件和MyDLL.lib文件。
二、DLL的使用(静态链接、隐式链接  )
创建项目->Win32控制台应用程序,名称:UseDLL。
将MyDLL.lib文件放在与UseDLL.exe文件的目录下。
创建源文件UseDll.cpp
UseDll.cpp代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// UseDll.cpp : 定义控制台应用程序的入口点。
//
#pragma comment (lib,"MyDLL.lib")
#include "stdafx.h"
#include <iostream>
using namespace std;
extern "C" _declspec(dllimport) int Add(int plus1, int plus2);   //或者直接在工程的Setting->Link页中设置导入MyDll.lib既可
int _tmain(int argc, _TCHAR* argv[])
{
int a = 20;
int b = 30;
cout<<"a+b="<<Add(a, b)<<endl;
getchar();
return 0;
}

运行结果如下:
a+b=50
三、DLL的使用(动态调用、显式链接)
创建项目->Win32控制台应用程序,名称:UseDLL。
将MyDLL.dll文件放在与UseDLL.exe文件的目录下。
创建源文件UseDll.cpp
UseDll.cpp代码如下: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// UseDll.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;
typedef int (*AddFunc)(int a,int b);
int _tmain(int argc, _TCHAR* argv[])
{
    HINSTANCE hInstLibrary = LoadLibrary(_T("MyDLL.dll"));//注意此处必须有_T()函数。
    if (hInstLibrary == NULL)    
    {    
        FreeLibrary(hInstLibrary); 
        cout<<"LoadLibrary error!"<<endl;
        getchar();
        return 0;
    }
    AddFunc _AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add");
    if (_AddFunc == NULL)
    {      
        FreeLibrary(hInstLibrary); 
        cout<<"GetProcAddress error!"<<endl;
        getchar();
        return 0;
    }
    cout <<"a+b="<<_AddFunc(20, 30) << endl;   
    getchar();
    FreeLibrary(hInstLibrary);
    return 0;
}

Cyper的笔记,第二步静态链接报如下错误

1>------ Build started: Project: testdll, Configuration: Debug Win32 ------
1>Linking...
1>testdll.obj : error LNK2019: unresolved external symbol __imp__Add referenced in function _wmain
1>C:\f\vsProject\Vc9.0\testdll\Debug\testdll.exe : fatal error LNK1120: 1 unresolved externals
1>Build log was saved at "file://c:\f\vsProject\Vc9.0\testdll\testdll\Debug\BuildLog.htm"
1>testdll - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

解决:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// UseDll.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
#pragma comment (lib,"MyDLL.lib")
extern "C" _declspec(dllimport) int Add(int plus1, int plus2);   //或者直接在工程的Setting->Link页中设置导入MyDll.lib既可
int _tmain(int argc, _TCHAR* argv[])
{
    int a = 20;
    int b = 30;
    cout<<"a+b="<<Add(a, b)<<endl;
    getchar();
    return 0;
}
把#prama这一行移到stdafx.h下面就没有错了(折腾了很久才试出来 )
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
将 动态链接库文件添加到VC程序中
利用VC调用动态链接库中的函数
在VC++中创建DLL文件并加载
Windows 动态链接库DLL
C/C /C#使用C/C 动态链接库DLL 错误现象及解决办法 图文详解
生成dll文件以及python对DLL中函数的调用(参数类型以及返回值)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服