以下代码是如何工作的(从DLL加载动态类)
How does the following code works(Dynamic Class loading from 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
之前的部分是什么,最好还有代码的其余部分。我知道这可能是一个很大的问题,但这确实会帮助我更好地理解这一点,因为我不知道这里发生了什么。
(ILogEngine* (*)())
是一个强制转换,它被强制转换为类型"不带参数的函数指针,并返回一个指向ILogEngine的指针"。
就像ILogEngine* (*create)();
是一个声明一样,它声明了一个变量create
,该变量的类型是(你猜对了)指向函数的指针,不带参数,并返回一个指向ILogEngine的指针。
ILogEngine* (*create)();
这是指向不带参数并返回ILogEngine*
的函数的指针的声明
create = (ILogEngine* (*)())GetProcAddress(handle, "create_object");
GetProcAddress
返回具有给定名称的函数的地址。(ILogEngine*)
将返回的地址(即void*
)强制转换为指定的类型。
在这之后,您在本地create
指针中有create_object
函数的地址(需要检查NULL
-可能函数在给定的dll中不存在?),所以您可以调用它。
动态加载的工作原理如下:
- LoadLibrary:加载DLL。返回的句柄被用了好几件事
- GetProcAddress-将导出的DLL函数映射到函数指针。您将看到此函数调用以及强制转换为函数指针类型
注意C++名称很难使用,因此映射的DLL导出通常具有C名称。在本例中,create_object
函数是用extern "C"
声明的。
create_object
,工厂函数创建一个C++对象,并返回类本身或已知基类(更常见)。
- 系统.将数组移交给c#中动态加载的c++DLL时发生AccessViolationException
- 在 Linux 平台的 C++ 中动态加载 DLL
- 在Qt C++单元测试中动态加载QQuickWindow而不是QQuickWidget
- 使用动态链接加载程序 <dlfcn.h> 而不是直接函数调用的目的是什么?
- 从 C 可执行文件加载动态库时收到错误C++"undefined symbol"
- 从动态加载的 dll 内部调用C++函数
- 使用CFBundleCreate在C++中的Mac上加载动态共享库(DLL)
- C/C++函数动态加载器(helper)
- 地址清理器和运行时加载动态库 ->(<未知模块>)
- 从zip、内存等加载动态库
- 我们可以在链接期间加载动态库吗
- 从内存加载动态库
- 加载动态链接库的第三种方法?大头针
- 以下代码是如何工作的(从DLL加载动态类)
- 通过链接到静态库加载动态库
- 在 Mac 中加载动态库路径错误
- 如何避免在c++项目(XCode)中在其他机器上加载动态库
- 无法在运行时加载动态共享库,包括C++中的另一个共享库
- 无法加载动态库/usr/lib/OGRE/RenderSystem_GL
- 是否有任何链接器标志告诉在打开后延迟加载动态库