DLL的显式调用与隐式调用

一直没分清楚,今天算是彻底明白了。

隐式调用

编译程序时需要头文件、lib文件,运行时需要DLL文件,并且运行过程中DLL文件一直被占用。

显式调用

编译时什么都不需要,在需要使用DLL中的函数时,通过LoadLibrary()和FindProcAdress()这两个API调用。

只需要一个DLL文件即可,而且在需要使用的时候DLL才被占用,使用完毕即被解除占用。DLL中有哪些函数可以通过Depends工具查询。


具体

在写DLL时,头文件中一般如此:

#ifdef DLL_EXPORT

#define DECLDIR __declspec(dllexport)

#else

#define DECLDIR __declspec(dllimport)

#endif


extern "C"

{

    DECLDIR void alert();

}

这样使得在定义了DLL_EXPORT的环境下,头文件中,函数为导出;相反为导入。

于是,我们可以使用同一个头文件。此时是在写DLL,还是在使用DLL,只需要通过这个开关来告诉编译器就可以了。


实现cpp中一般这么写:

#include "stdafx.h"


#define DLL_EXPORT

#include "MyHead.h"


extern "C"

{

    DECLDIR void alert()

    {

        MessageBoxA(NULL, "Hello,World!", 0, 0);

    }

}

在引用头文件前定义DLL_EXPORT,告诉编译器此时这些函数需要导出。


隐式调用

#include "stdafx.h"

#include "MyHead.h"

#pragma comment(lib,"MyTestDLL.lib")


int _tmain(int argc, _TCHAR* argv[])

{

    alert();    // 直接调用

    return 0;

}

由于我们没有定义DLL_EXPORT,那么头文件中的函数就会被从DLL中导入。


显式调用


#include "stdafx.h"

#include <windows.h>


typedef void (*alert)();


int _tmain(int argc, _TCHAR* argv[])

{

    alert func = NULL;

    HINSTANCE h = LoadLibraryA("MyTestDLL.dll");

    if (h)

    func = (alert)GetProcAddress(h, "alert");

    if (NULL != func)

    func();

    FreeLibrary(h);


    return 0;

}

首先定义函数指针类型,然后实例化一个该类型的函数。最后调用即可。


以上。

你可能感兴趣的:(C++,dll,调用)