当使用运行时加载dll时,vc++可以共享库中的静态信息

Can vc++ share statics in a a library when using runtime dll loading

本文关键字:共享 信息 静态 vc++ 运行时 加载 dll      更新时间:2023-10-16

我正在研究一个使用Microsoft c++的插件类型系统。问题是我不能在主程序和插件库之间的共享库中共享静态变量。

主程序:

#include "stdafx.h"
#include "windows.h"
#include "..EngineLibEngine.h"
typedef void(*PluginFuncPtrType)(void);
int main()
{
    printf("Main Test.n");
    HINSTANCE hRuntimeDll = LoadLibrary(L"PluginLib.dll");
    if (!hRuntimeDll) {
        printf("Could not load the dynamic library.n");
    }
    PluginFuncPtrType pluginFuncPtr = (PluginFuncPtrType)GetProcAddress(hRuntimeDll, "PluginFunc");
    if (!pluginFuncPtr) {
        printf("Could not load the function from dynamic library.n");
    }
    else {
        pluginFuncPtr();
        printf("Main engine counter %i.n", EngineFunc());
        pluginFuncPtr();
        printf("Main engine counter %i.n", EngineFunc());
        pluginFuncPtr();
        printf("Main engine counter %i.n", EngineFunc());
    }
    printf("Press any key to exit...");
    getchar();
}

主程序(静态链接)和插件dll(也在此共享库中静态链接)使用的共享库

共享库头文件(Engine.h):

#pragma once
#include <stdio.h>
int EngineFunc();

共享库实现:

#include "stdafx.h"
#include "Engine.h"
#include <stdio.h>
static int _engineCounter = 1;
int EngineFunc()
{
    return _engineCounter++;
}

插件dll头文件(Plugin.h):

#pragma once
#include "stdafx.h"
#include <stdio.h>
#include "..EngineLibEngine.h"
extern "C" __declspec(dllexport) void PluginFunc(void);
插件实现:

#include "Plugin.h"
void PluginFunc(void)
{
    printf("PluginFunc engine counter=%in", EngineFunc());
}

main.exe输出:

Main Test.
PluginFunc engine counter=1
Main engine counter 1.
PluginFunc engine counter=2
Main engine counter 2.
PluginFunc engine counter=3
Main engine counter 3.
Press any key to exit...

Main.exe静态链接到 engineellib .libPluginLib.dll静态链接到 engineellib .lib.

Main不链接PluginLib.dll,而是在运行时加载。

从我所理解的,当一个dll在运行时使用LoadLibrary加载,它得到它自己的虚拟内存地址空间,因此不同的静态变量到相同的库静态链接到主程序。我相信在Linux上动态加载的库确实共享相同的虚拟内存空间。

我的问题是是否有任何方法我可以使用Windows允许动态加载的dll使用相同的静态变量作为静态链接库?

创建dll。"EngineStatics.dll"。在此dll中定义static,并使用__declspec(dllexport)将其导出。

在您的exe中,添加对上述dll的依赖项。并使用__declspec(dllimport)声明相同的静态。

在你的插件dll中,添加对同一个dll的依赖,并使用delcspec(dllimport)

导入它

这似乎比我最初的答案简单得多,直接从。EXE导出静态文件,联合工具生成一个导出库,然后使插件dll链接到EXE的库文件。