以下代码如何工作(从DLL加载动态类)?

时间:2013-12-04 10:37:37

标签: c++ class dynamic dll

我想编写类并将它们导出到DLL中,然后在我的C ++应用程序中使用它们。我在网上搜索,经过几天的研究,我终于找到了解决方案。问题是我无法正确理解代码。我不想盲目地使用代码。我想知道它到底在做什么。这是我的代码。 这是主要的应用程序源main.cpp

#include <Windows.h>
#include <iostream>
#include <conio.h>
#include "ILogEngine.hpp"

using namespace std;

int main(int argc, char **argv)
{
    HINSTANCE handle = LoadLibrary("LogEngine.dll");
    if (handle == NULL)
    {
    MessageBoxA(NULL, "LogEngine.dll not found!!!", "Fatal Error!!!", MB_ICONERROR);
    exit(1);
    }

    ILogEngine* (*create)();
    void (*destroy)(ILogEngine*);

    create = (ILogEngine* (*)())GetProcAddress(handle, "create_object");
    destroy = (void (*)(ILogEngine*))GetProcAddress(handle, "destroy_object");

    ILogEngine* logEngine = (ILogEngine*)create();
    logEngine->msg();
    destroy(logEngine);
_getch();
    return 0;
}

这是ILogEngine.hpp

#ifndef __ILOGENGINE_HPP
#define __ILOGENGINE_HPP

class ILogEngine
{
public:
ILogEngine();
virtual void msg();
virtual int genLog(char *);
};
#endif

这是该类的LogEngine.cpp实现。

#include "ILogEngine.hpp"
#include <iostream>

using namespace std;

#define DLL_EXPORT __declspec(dllexport)

extern "C" DLL_EXPORT ILogEngine* create_object()
{
    return new ILogEngine;
}

extern "C" DLL_EXPORT void destroy_object( ILogEngine* object)
{
    delete object;
}

ILogEngine::ILogEngine()
{
}

void ILogEngine::msg()
{
    cout << "This is a message from DLL..." << endl;
}

我能够理解部分内容,但无法理解整个过程。任何人都可以指导一下这里发生了什么? 具体来说,(ILogEngine* (*)())之前的GetProcAddress部分是什么,也最好是代码的其余部分。我知道这可能有很多要问,但它会帮助我更好地理解这一点,因为我不知道这里发生了什么。

3 个答案:

答案 0 :(得分:1)

(ILogEngine* (*)())是一个强制类型转换器,它被转换为类型'指向函数的指针,该函数不带参数并返回指向ILogEngine的指针'。

以同样的方式ILogEngine* (*create)();是一个声明,它声明了一个变量create,该变量的类型是(你猜对了)指向函数的指针,不带参数并返回一个指向ILogEngine的指针

答案 1 :(得分:1)

ILogEngine* (*create)();

这是指向函数的指针的声明,它不带参数并返回ILogEngine*

create = (ILogEngine* (*)())GetProcAddress(handle, "create_object");

GetProcAddress返回具有给定名称的函数的地址。 (ILogEngine*)将返回的地址(void*)强制转换为指定的类型。

在此之后,您在本地create_object指针中有create函数的地址(需要检查NULL - 可能在给定的dll中不存在函数?),所以你可以打电话给它。

答案 2 :(得分:0)

动态加载的工作原理如下:

  • LoadLibrary:加载DLL。返回的句柄有几个用处。
  • GetProcAddress - 将导出的DLL函数映射到函数指针。您将看到此函数调用以及强制转换为函数指针类型。

注意C ++名称很难使用,因此映射的DLL导出通常具有C名称。 在此示例中,create_object函数已使用extern "C"声明。

create_object,工厂函数创建一个C ++对象并返回类本身或已知的基类(更常见)。